本來想寫x名稱空間詳解,但是看了很多語法還需要好好的看一下,所以就等到下一篇了。如果文章中有不懂的話,可以留言,或者是等到下一篇的時間回頭看看,應該就會明白了。
一.再說XAML
XAML是一種專門繪制UI的語言,借助它可以把UI與運行邏輯分離開來。XAML使用標簽定義UI元素,每一個標簽對應.NET Framework類庫的一個控件類。通過設置標簽的Attribute,不僅可以對標簽所對應的控件對象Property進行賦值,還可以聲明名稱空間,指定類名等。XAML文檔是樹形的,在WPF中布局設計會影響到ui的顯示效果,具體的會在下一節詳細說明。在此給出一個簡單的例子,Xaml的代碼如下:
<Window x:Class="Chap_02.MainWindow" 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> <Rectangle x:Name="rectangle" Width="200" Fill="Blue"></Rectangle> <TextBox x:Name="textBox1" Width="50" Background="Red"></TextBox> </Grid> </Window>
把上面<Grid>標簽換成<StackPanel>觀察結果。
二.初始化對象的屬性——為對象屬性賦值
2.1使用Attribute為對象屬性賦值
XAML是一種聲明性語言,XAML編譯器會為每個標簽創建一個與之對應的對象,之后要對他的屬性進行初始化才會有意義。所以,每個標簽除了聲明對象就是初始化對象的屬性--即給其屬性賦值。賦值方法有兩種:一種是字符串簡單賦值(在XAML中賦值),另外一種是使用屬性元素進行復雜賦值(在.cs里面賦值)。下面的例子用xaml賦值,前台代碼:
<Windowx:Class="Chap_02.MainWindow" 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> <Rectangle x:Name="rectangle" Width="200" Fill="Blue"></Rectangle> </Grid> </Window>
后台代碼為默認代碼,用.cs賦值,其中前台代碼為上面的代碼的一部分,把Fill="Blue"去掉
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace Chap_02 { /// <summary> /// MainWindow.xaml 的交互邏輯 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); SolidColorBrush scb = new SolidColorBrush(); scb.Color = Colors.Blue; this.rectangle.Fill = scb; } } }
在這里或許你會感覺到xaml的強大了;幾個字母搞定的,.cs要好多行,這個好像是白話文和古文的區別一樣,各有優勢和略勢。下面解釋一下Fill屬性,其值類型是Brush,但是Brush又是一個抽象類(由於抽象類不能實例化),所以只有用抽象類的子類的實例進行賦值。既然上面用到筆刷類,下面就給出Brush的派生類及其描述:
· SolidColorBrush:使用純 Color 繪制區域。
· LinearGradientBrush:使用線性漸變繪制區域。
· RadialGradientBrush:使用徑向漸變繪制區域。
· ImageBrush:使用圖像(由 ImageSource 對象表示)繪制區域。
· DrawingBrush:使用 Drawing 繪制區域。 繪圖可能包含向量和位圖對象。
· VisualBrush:使用 Visual 對象繪制區域。 使用 VisualBrush 可以將內容從應用程序的一個部分復制到另一個區域,這在創建反射效果和放大局部屏幕時會非常有用。
2.2使用TypeConvert類將XAML標簽的Attribute與對象的Property進行映射
由於XAML的屬性元素賦值形式為Attribute=value且value是一個字符串的緣故,我們前面說過Attribute和對象的Property對應,如果在后台獲取對象的Property呢?如果是直接獲取的話多數會看到轉化失敗的提示,因為Property的類型不一定為string類型的。為了解決這個問題,我們利用的是TypeConverter類,對於這個類微軟官方的解釋:
提供一種將值類型轉換為其他類型的統一方式。 TypeConverter 通常支持字符串到對象的轉換,目的是供設計環境中的屬性編輯器使用或者是為了能夠使用 XAML。
下面就給出一個例子來看看:
需求是這樣的,我給出一個類,在XAML中的某個元素里(由於剛剛開始,所以就叫某個元素吧,到后面我們會發現他叫資源)存儲一個類為Human的對象,含有名字和兒子,兒子的類型也是Human,其中在XAML里為兒子賦值為兒子的名字。然后在UI上放一個按鈕,當我點擊UI上的按鈕時彈出兒子的名字。 XAML的代碼為:
<Window x:Class="Chap_02.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:Chap_02" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <local:Human x:Key="human" Child="ABC"></local:Human> </Window.Resources> <Grid> <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="56,78,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click"/> </Grid> </Window>
順便把后台代碼頁貼出來吧
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.ComponentModel; namespace Chap_02 { /// <summary> /// MainWindow.xaml 的交互邏輯 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } //點擊按鈕事件 private void button1_Click(object sender, RoutedEventArgs e) { Human h =(Human) this.FindResource("human"); MessageBox.Show(h.Child.Name); } } //人類 public class Human { public string Name { get; set; } public Human Child { get; set; } } }
直接運行,點擊按鈕會出現異常,無法將字符串轉成Human類,在Human類下面加上一個TypeConverter的派生類,重寫ConvertFrom方法, 還是上代碼吧!!
public class StringToHumanTypeConverter : TypeConverter
{
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
Human h = new Human();
h.Name = value as string;
return h;
}
return base.ConvertFrom(context, culture, value);
}
}
除此之外還要在Human類前加[TypeConverter(typeof(StringToHumanTypeConverter))]其中TypeConverter是TypeConverterAttribute的縮寫。現在再單擊按鈕,應該就會彈出child的name來了。
2.3通過屬性元素解決Attribute=value的復雜的value
由於value是字符串,由於種種原因字符串經常容易寫錯,特別是比較長或者沒有規律的字符串,但是作為程序員幸運的是有屬性元素(在vs平台上可以智能提示)。不明思議,屬性元素就是某個標簽的一個屬性用元素(或者說標簽)表達出來。如下面的例子,直接給出XAML代碼:
<Window x:Class="Chap_02_PropertyElement.MainWindow" 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> <Rectangle HorizontalAlignment="Left" Margin="73,75,0,150" Stroke="Black" Width="170"> <Rectangle.Fill> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="Black" Offset="0"/> <GradientStop Color="#FF668D2F" Offset="1"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> </Grid> </Window>
運行結果時一個漸變的矩形,如果是要讓我們用Fill的表達的話,那是有點難度的吧,現在用了屬性元素,至少.NET平台會給我們提示甚至不用提示,用blend很簡單的就出來了一個漸變效果。
2.4標簽擴展
為了同一個對象賦值給兩個對象的屬性,或者是需要隊形的屬性賦一個null值等功能,現在引入標記擴展。先通過一個例子來說明吧!老規矩說需求,在一個文本框里面顯示一個slider的值。效果圖如下:
圖1
其代碼為:
<Window x:Class="xNameSpace.MarkExtensions" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MarkExtensions" Height="300" Width="300"> <StackPanel> <TextBox Text="{Binding ElementName=slider1,Path=Value,Mode=OneWay}" Margin="5"/> <Slider x:Name="slider1" Margin="5"/> </StackPanel> </Window>
主要說明是 <TextBox Text="{Binding ElementName=slider1,Path=Value,Mode=OneWay}" Margin="5"/>這一句,擴展標簽對象的類型為花括號最左邊的單詞,花括號里面的值不需要再加括號。具體的細節不要太在意,以后的章節會再具體說明,目前只需要了解一下有這么一回事。
三、導入程序集合引用其中的名稱空間
在項目里面建一個類庫Common,和一個xaml項目Chap_02,然后生成。XAML中的引用名稱空間和程序集的格式:
xmlns:映射名="clr-namespace:名稱空間;assembly=程序集名"
對應XAML的引用為:
xmlns:common="clr-namespace:Common;assembly=Common"
<common:類名></common:類名>
四、總結
本文主要說明說明了TypeConverter和屬性元素,最后介紹了導入程序集和命名空間。如有不足的地方,還請大家指出,謝謝閱讀!下一節,x名稱空間詳解。