zoukankan      html  css  js  c++  java
  • [转]如何实现类的Property与标签的Attribute映射

    我们知道,XAML标签会对应一个实例。如果在XAML里初始化实例的属性,我们有两种语法可以选择:

    • 直接使用Attribute="Value"的方法
    • 属性元素(Property Element)方法

    今天我们讨论的核心就是——第一种方法是如何实现的。

    先看一个例子。我为一个Grid设置了矢量渐变画刷:

    1.     <Grid>
    2.         <Grid.Background>
    3.             <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
    4.                 <GradientStop Offset="0" Color="White"/>
    5.                 <GradientStop Offset="0.5" Color="LawnGreen"/>
    6.                 <GradientStop Offset="1" Color="White"/>
    7.             </LinearGradientBrush>
    8.         </Grid.Background>
    9.     </Grid>

    效果是这样:

     

    请大家注意StartPoint="0,0" EndPoint="1,1这两个Attribute,它们实际上对应的是实例的两个属性。如果查看MSDN,你会发现这两个属性的数据类型是Point而不是String。那么,一个string类型值是如何被转换成Point类型值的呢?

     

    让我们自己动手DIY一个!

     

    首先,我们准备了一个类:

     

    1.     public class Human
    2.     {
    3.         public string Name { getset; }
    4.         public Human Child { getset; }
    5.     }

    这个类具有两个属性

    • string类型的Name
    • Human类型的Child

    现在我的期望是,如果我在XAML里这样写:

    1.     <Window.Resources>
    2.         <local:Human x:Key="human" Child="ABC"/>
    3.     </Window.Resources>

    则能够为Human实例的Child赋一个Human类型的值,并且Child.Name就是这个字符串的值。

    我们先看看直接写行不行……

    我在UI上添加了一个按钮button1,并在它的Click事件处理器里写上:

    1.         private void button1_Click(object sender, RoutedEventArgs e)
    2.         {
    3.             Human h = (Human)this.FindResource("human");
    4.             MessageBox.Show(h.Child.Name);
    5.         }

    编译没有问题,但在我点击按钮之后程序抛出异常——告诉我Child不存在。那我们应该怎么做呢?

    办法是使用TypeConverter和TypeConverterAttribute这两个类。

     

    首先,我们要从TypeConverter类派生出自己的类,并重写它的一个ConvertFrom方法。这个方法有一个参数名为value,这个值就是在XAML文档里为它设置的值。我们要做的就是把这个值“翻译”成合适类型的值、赋给对象的属性:

    1.     public class StringToHumanTypeConverter : TypeConverter
    2.     {
    3.         public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    4.         {
    5.             if (value is string)
    6.             {
    7.                 Human h = new Human();
    8.                 h.Name = value as string;
    9.                 return h;
    10.             }
    11.             return base.ConvertFrom(context, culture, value);
    12.         }
    13.     }

    有了这个类还不够,还要使用TypeConverterAttribute这个特征类把StringToHumanTypeConverter这个类“粘贴”到作为目标的Human类上。

    1.     [TypeConverterAttribute(typeof(StringToHumanTypeConverter))]
    2.     public class Human
    3.     {
    4.         public string Name { getset; }
    5.         public Human Child { getset; }
    6.     }

    因为特征类在使用的时候可以省略Attribute这个词,所以我们也可以写成:

    1.     [TypeConverter(typeof(StringToHumanTypeConverter))]
    2.     public class Human
    3.     {
    4.         public string Name { getset; }
    5.         public Human Child { getset; }
    6.     }

    但这样写,我们需要认清写在方括号里的是TypeConverterAttribute而不是TypeConverter。

     

    完成之后,再次点击按钮,我们想要的结果就出来了!

     

     

    文章来源:http://blog.csdn.net/fantasiax/article/details/3727224

     

  • 相关阅读:
    Navicat远程连接服务器Mysql
    JSP与Servlet之间传值
    JSP获取绝对路径
    PIL的库学习
    科学计算与可视化
    预测球类比赛结果
    预测球类比赛结果
    汉诺塔问题
    有进度条圆周率计算
    turtle学习心得
  • 原文地址:https://www.cnblogs.com/luohengstudy/p/3096984.html
Copyright © 2011-2022 走看看