WPF 之 XAML語法,物件屬性賦值(簡單賦值、TypeConverter 標籤屬性與物件屬性對映、標記擴充套件),引用外部庫
一、XAML樹形結構
框架都是樹形的,以<Window>物件為根節點,一層一層向下包含。這種樹形結構對於WPF整個體系都具有非常重要的意義,它不但影響著UI的佈局設計,還深刻的影響著WPF的屬性(Property)子系統和事件(Event)子系統等方方面面。在實際的程式設計過程中,我們經常要在這棵樹上進行按名稱查詢元素,獲取父/子節點等操作,為了方便操作這棵樹,WPF基本類庫為程式設計師準備了 VisualTreeHelper 和 LogicTreeHelper 兩個助手類(Helper Class),同時還在一些重要的基類裡封裝了一些專門用於操作這棵樹的方法。
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="532" Loaded="Window_Loaded"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="250*" /> <ColumnDefinition Width="266*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="42" /> <RowDefinition Height="48" /> <RowDefinition Height="66" /> <RowDefinition Height="153" /> </Grid.RowDefinitions> <TextBox HorizontalAlignment="Center" Margin="10,10,0,0" Name="textBox1" VerticalAlignment="Top" Grid.ColumnSpan="2"/> <TextBox HorizontalAlignment="Center" Margin="10,10,0,0" Name="textBox2" VerticalAlignment="Top" Grid.Row="1" Grid.ColumnSpan="2"/> <TextBox HorizontalAlignment="Right" Margin="10,10,0,0" Name="textBox3" VerticalAlignment="Top" Grid.Row="2" Grid.Column="0"/> <TextBox HorizontalAlignment="Left" Margin="10,10,0,0" Name="textBox4" VerticalAlignment="Top" Grid.Row="2" Grid.Column="1"/> <Button HorizontalAlignment="Center" Margin="10,10,0,0" Name="button1" VerticalAlignment="Top" Grid.Row="3" Grid.ColumnSpan="2"> </Button> </Grid> </Window>
二、XAML中為物件屬性賦值的方法
XAML是一種宣告性語言,XAML會為每一個標籤建立一個與之對於的物件,物件建立之後要對它的屬性進行必要的初始化之後才有使用意義。因為XAML語言不能夠編寫程式的執行邏輯,所以一份XAML文件除了使用標籤宣告物件就是初始化物件屬性了。
注意:
XAML中對物件賦值總共有兩種方法:
1、:使用字串進行簡單賦值。
2、:使用屬性元素(Property Element)進行復雜賦值 (使用TypeConverter類將XAML標籤的Attribute與物件的Property進行對映)。
使用TypeConverter類將XAML標籤的Attribute
(1)建立類Human,型別轉換器TypeConvertAttribute
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; namespace WpfApplication1 { //型別轉換器TypeConvertAttribute [TypeConverter(typeof(StringToHumanTypeConverter))] public class Human { public string Name{get;set;} public Human Child { get; set; } } }
(2)、從TypeConvert派生出自己的類,並重寫它的ConverFrom方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace WpfApplication1
{
//首先,我們要從TypeConvert派生出自己的類,並重寫它的ConverFrom方法。
//這個方法有一個引數名叫做Value,這個值就是XAML文件裡面為其設定的值。我們要做的就是將這個值翻譯成合適物件的值並賦值給物件的屬性:
public class StringToHumanTypeConverter : TypeConverter
{
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
Human human = new Human();
human.Name = value as string;
return human;
}
return base.ConvertFrom(context, culture, value);
}
}
}
(3)XAML引用名稱空間,呼叫類
引用名稱空間:WpfApplication1
xmlns:local="clr-namespace:WpfApplication1"
Window.Resources 定義一個Window級的Resources ,這只是一種以Window級的資源的定義.
其實Resources的定義可以在每一個容器控制元件中,(或者是在每一個控制元件,在Template 中可以用到),像C#中變數的定義一樣,Resource的定義的地方不同
也就決定它的作用範圍,如:
Window.Resources它的作用範圍就是在Window容器裡的所有子控制元件有效,也只有這些只控制元件才能引用/呼叫這些資源
Grid.Resources它的作用範圍就是在Grid容器裡的所有子控制元件有效,也只有這些只控制元件才能引用/呼叫這些資源
以此類推....
請注意:Window不是最上層的"容器",最上層的應該是Appication ,所以Application.Resources 的作用範圍更大(有人把Application.Resource叫作全域性資源,所有在這個Application下的容器控制元件等都可以使用,常用來做一個應該程式的Skin ,其ResourceDictionary定義的資源也類似 )
(<<我眼裡的XAML結構框架>>概括為:"一個Application下有多個Window ,一個Window下有一個Grid,一個Grid下有很多佈局容器,這些容器裡面有好子容器或控制元件 ,控制元件裡面有Template,template裡面又可以裡Grid…… ")
(4)按鈕事件
private void button1_Click(object sender, RoutedEventArgs e)
{
Human human = (Human)this.FindResource("human123");
MessageBox.Show(human.Child.Name);
}
標記擴充套件:有一對花括號及其括起來的內容組成,XAML編譯器會對這樣的內容做解析、生成相應的物件。
<TextBox Margin="5" Text="{Binding ElementName=slider1, Path=Value}" />
<Slider x:Name="slider1" Margin="5"/>
三、其他XAML語法
(1)引用外部庫
clr-namespace:名稱空間名稱;assembly=外部*.dll
(2) 訪問修飾符
<Window x:Class="WpfApplication1.MainWindow" x:ClassModifier="internal"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Height="100" Width="100" x:FieldModifier="public"/>
</Grid>
</Window>
(3)屬性元素
為屬性賦予複雜物件。
<Button Height="100" Width="100" Content="OK">
<Button.Background>
<LinearGradientBrush>
<GradientStop Color="DarkGreen" Offset="0"/>
<GradientStop Color="LightGreen" Offset="1"/>
</LinearGradientBrush>
</Button.Background>
</Button>
(4) 附加屬性
在WPF佈局管理器類(Grid、DockPanel等)中 定位 UI元素
<Canvas>
<Button Canvas.Top="40"/>
</Canvas>
(5)標記擴充套件
XAML 解析器從專門的 外部類 中獲取屬性的值。這是非常有好處的,因為有些屬性需要一些程式碼語句來計算其值。
前言:XAML有時需要一些標準功能或者預設行為無法滿足的功能,比如屬性賦值,它可能並不是直接賦一個字串,而是要對已定義的物件的一個引用,由此便誕生了標記擴充套件。
標記擴充套件的語法是使用“{}”,例如 Map={bindingelementname=”myMap“}
標記擴充套件可分為以下幾類:
a、基於WPF的標記擴充套件
StaticResource:通過引用已定義資源的值來為XAML屬性提供值。
DynamicResource:通過將資源的引用推遲到執行時來為XAML屬性提供值。動態資源引用強制來每次訪問此類資源時都進行重新訪問。
Binding:按引用於元素的資料上下文來為屬性提供資料繫結值。
RelativeSource:在執行時,為了可以在元素樹中定位若干可能關係的Binding提供源資訊。
TemplateBinding:提供資料模板繫結。
b、XAML定義的標記擴充套件
x:Type:為所提供的型別提供Type物件。
x:Static:為屬性值提供已定義的靜態值。該靜態值必須在引用之前定義。
x:Null:將null指定為XAML屬性的值。
x:Array:為XAML中常規陣列的建立提供支援