小序:
咳咳,我知道這個標題不太好讓人明白。
它的意思是這樣——咱們知道,用C#代碼編寫的類也能夠在XAML文檔裏聲明實例,聲明以後咱們可使用XAML的Attribute對實例的 Property進行賦值。但XAML標籤的Attribute只能接受string類型的值,若是像int、double這類簡單的值還好辦,若是是復 雜的值呢?咱們應該怎麼辦?
正文:
咱們知道,XAML標籤會對應一個實例。若是在XAML裏初始化實例的屬性,咱們有兩種語法能夠選擇:
- 直接使用Attribute="Value"的方法
- 屬性元素(Property Element)方法
今天咱們討論的核心就是——第一種方法是如何實現的。
先看一個例子。我爲一個Grid設置了矢量漸變畫刷:
- <Grid>
- <Grid.Background>
- <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
- <GradientStop Offset="0" Color="White"/>
- <GradientStop Offset="0.5" Color="LawnGreen"/>
- <GradientStop Offset="1" Color="White"/>
- </LinearGradientBrush>
- </Grid.Background>
- </Grid>
效果是這樣:
請你們注意
StartPoint
=
"0,0"
EndPoint
=
"1,1這兩個Attribute,它們實際上對應的是實例的兩個屬性。若是查看MSDN,你會發現這兩個屬性的數據類型是Point而不是String。那麼,一個string類型值是如何被轉換成Point類型值的呢?
讓咱們本身動手DIY一個!
首先,咱們準備了一個類:
- public class Human
- {
- public string Name { get; set; }
- public Human Child { get; set; }
- }
這個類具備兩個屬性
-
string類型的Name
-
Human類型的Child
如今個人指望是,若是我在XAML裏這樣寫:
- <Window.Resources>
- <local:Human x:Key="human" Child="ABC"/>
- </Window.Resources>
則可以爲Human實例的Child賦一個Human類型的值,而且Child.Name就是這個字符串的值。
咱們先看看直接寫行不行……
我在UI上添加了一個按鈕button1,並在它的Click事件處理器裏寫上:
- private void button1_Click(object sender, RoutedEventArgs e)
- {
- Human h = (Human)this.FindResource("human");
- MessageBox.Show(h.Child.Name);
- }
編譯沒有問題,但在我點擊按鈕以後程序拋出異常——告訴我Child不存在。那咱們應該怎麼作呢?
辦法是使用TypeConverter和TypeConverterAttribute這兩個類。
首先,咱們要從TypeConverter類派生出本身的類,並重寫它的一個ConvertFrom方法。這個方法有一個參數名爲value,這個值就是在XAML文檔裏爲它設置的值。咱們要作的就是把這個值「翻譯」成合適類型的值、賦給對象的屬性:
- 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);
- }
- }
有了這個類還不夠,還要使用TypeConverterAttribute這個特徵類把StringToHumanTypeConverter這個類「粘貼」到做爲目標的Human類上。
- [TypeConverterAttribute(typeof(StringToHumanTypeConverter))]
- public class Human
- {
- public string Name { get; set; }
- public Human Child { get; set; }
- }
由於特徵類在使用的時候能夠省略Attribute這個詞,因此咱們也能夠寫成:
- [TypeConverter(typeof(StringToHumanTypeConverter))]
- public class Human
- {
- public string Name { get; set; }
- public Human Child { get; set; }
- }
但這樣寫,咱們須要認清寫在方括號裏的是TypeConverterAttribute而不是TypeConverter。
完成以後,再次點擊按鈕,咱們想要的結果就出來了!
TO BE CONTINUED...