• 稳扎稳打Silverlight(65) 5.0绑定之通过 ICustomTypeProvider 绑定动态生成的属性


    [索引页]
    [源码下载]


    稳扎稳打Silverlight(65) - 5.0绑定之通过 ICustomTypeProvider 绑定动态生成的属性



    作者:webabcd


    介绍
    Silverlight 5.0 绑定

    • 绑定动态生成的属性



    在线DEMO
    http://www.cnblogs.com/webabcd/archive/2012/03/05/2379862.html


    示例
    Binding/DynamicProperty.xaml

    <navigation:Page x:Class="Silverlight50.Binding.DynamicProperty" 
    xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d
    ="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc
    ="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable
    ="d"
    xmlns:navigation
    ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
    d:DesignWidth
    ="640" d:DesignHeight="480"
    Title
    ="DynamicProperty Page"

    xmlns:sdk
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">

    <Grid x:Name="LayoutRoot">
    <sdk:DataGrid Name="dgProducts" AutoGenerateColumns="True" />
    </Grid>
    </navigation:Page>


    Binding/DynamicProperty.xaml.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Navigation;

    namespace Silverlight50.Binding
    {
    public partial class DynamicProperty : Page
    {
    public DynamicProperty()
    {
    InitializeComponent();

    this.Loaded += new RoutedEventHandler(DynamicProperty_Loaded);
    }

    void DynamicProperty_Loaded(object sender, RoutedEventArgs e)
    {
    // 动态地为 Product 类型增加属性
    Product.AddProperty("Age", typeof(int));
    Product.AddProperty("Favorite", typeof(bool));

    Product product = new Product { Name = "3DS", Category = "游戏机", Price = 1100d };

    // 为 Product 中的动态生成的属性赋值
    product.SetPropertyValue("Age", 1);
    product.SetPropertyValue("Favorite", true);

    List<Product> products = new List<Product>();
    products.Add(product);

    // 由于 Product 实现了 ICustomTypeProvider 接口,所以动态生成的属性会被绑定到 DataGrid 控件上
    dgProducts.ItemsSource = products;
    }

    // Product 实现了 ICustomTypeProvider 接口,实现此接口的话可以绑定动态生成的属性
    class Product : CustomTypeHelper<Product>
    {
    public string Name { get; set; }
    public string Category { get; set; }
    public double Price { get; set; }
    }
    }
    }


    Binding/CustomTypeHelper.cs

    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;

    using System.Reflection;
    using System.ComponentModel;
    using System.Collections.Generic;
    using System.Linq;

    namespace Silverlight50.Binding
    {
    /// <summary>
    /// 实现了 ICustomTypeProvider 和 INotifyPropertyChanged 的自定义类型的帮助类
    /// </summary>
    public class CustomTypeHelper<T> : ICustomTypeProvider, INotifyPropertyChanged
    {
    private static List<CustomPropertyInfoHelper> _customProperties = new List<CustomPropertyInfoHelper>();
    private Dictionary<string, object> _customPropertyValues;
    private CustomType _ctype;
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info)
    {
    if (PropertyChanged != null)
    {
    PropertyChanged(this, new PropertyChangedEventArgs(info));
    }
    }

    public CustomTypeHelper()
    {
    _customPropertyValues = new Dictionary<string, object>();
    foreach (var property in this.GetCustomType().GetProperties())
    {
    _customPropertyValues.Add(property.Name, null);
    }
    }

    public static void AddProperty(string name)
    {
    if (!CheckIfNameExists(name))
    _customProperties.Add(new CustomPropertyInfoHelper(name, typeof(String)));
    }

    public static void AddProperty(string name, Type propertyType)
    {
    if (!CheckIfNameExists(name))
    _customProperties.Add(new CustomPropertyInfoHelper(name, propertyType));
    }

    public static void AddProperty(string name, Type propertyType, List<Attribute> attributes)
    {
    if (!CheckIfNameExists(name))
    _customProperties.Add(new CustomPropertyInfoHelper(name, propertyType, attributes));
    }

    private static bool CheckIfNameExists(string name)
    {
    if ((from p in _customProperties select p.Name).Contains(name) || (from p in typeof(T).GetProperties() select p.Name).Contains(name))
    throw new Exception("已存在同名属性:" + name);
    else return false;
    }

    public void SetPropertyValue(string propertyName, object value)
    {
    CustomPropertyInfoHelper propertyInfo = (from prop in _customProperties where prop.Name == propertyName select prop).FirstOrDefault();
    if (!_customPropertyValues.ContainsKey(propertyName))
    throw new Exception("无此属性:" + propertyName);
    if (ValidateValueType(value, propertyInfo._type))
    {
    if (_customPropertyValues[propertyName] != value)
    {
    _customPropertyValues[propertyName] = value;
    NotifyPropertyChanged(propertyName);
    }
    }
    else throw new Exception("值的类型错误或者对一个非空类型设置为 null");
    }

    private bool ValidateValueType(object value, Type type)
    {
    if (value == null)
    // 引用类型可以被标记为 null
    if (!type.IsValueType)
    return true;
    else
    return (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>));
    else
    return type.IsAssignableFrom(value.GetType());
    }

    public object GetPropertyValue(string propertyName)
    {
    if (_customPropertyValues.ContainsKey(propertyName))
    return _customPropertyValues[propertyName];
    else
    throw new Exception("无此属性:" + propertyName);
    }

    public PropertyInfo[] GetProperties()
    {
    return this.GetCustomType().GetProperties();
    }

    public Type GetCustomType()
    {
    if (_ctype == null)
    {
    _ctype = new CustomType(typeof(T));
    }
    return _ctype;
    }

    /// <summary>
    /// 继承抽象类 Type,以实现自定义的 Type
    /// </summary>
    private class CustomType : Type
    {
    Type _baseType;
    public CustomType(Type delegatingType)
    {
    _baseType = delegatingType;
    }
    public override Assembly Assembly
    {
    get { return _baseType.Assembly; }
    }

    public override string AssemblyQualifiedName
    {
    get { return _baseType.AssemblyQualifiedName; }
    }

    public override Type BaseType
    {
    get { return _baseType.BaseType; }
    }

    public override string FullName
    {
    get { return _baseType.FullName; }
    }

    public override Guid GUID
    {
    get { return _baseType.GUID; }
    }

    protected override TypeAttributes GetAttributeFlagsImpl()
    {
    throw new NotImplementedException();
    }

    protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
    {

    throw new NotImplementedException();
    }

    public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
    {
    return _baseType.GetConstructors(bindingAttr);
    }

    public override Type GetElementType()
    {
    return _baseType.GetElementType();
    }

    public override EventInfo GetEvent(string name, BindingFlags bindingAttr)
    {
    return _baseType.GetEvent(name, bindingAttr);
    }

    public override EventInfo[] GetEvents(BindingFlags bindingAttr)
    {
    return _baseType.GetEvents(bindingAttr);
    }

    public override FieldInfo GetField(string name, BindingFlags bindingAttr)
    {
    return _baseType.GetField(name, bindingAttr);
    }

    public override FieldInfo[] GetFields(BindingFlags bindingAttr)
    {
    return _baseType.GetFields(bindingAttr);
    }

    public override Type GetInterface(string name, bool ignoreCase)
    {
    return _baseType.GetInterface(name, ignoreCase);
    }

    public override Type[] GetInterfaces()
    {
    return _baseType.GetInterfaces();
    }

    public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
    {
    return _baseType.GetMembers(bindingAttr);
    }

    protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
    {
    throw new NotImplementedException();
    }

    public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
    {
    return _baseType.GetMethods(bindingAttr);
    }

    public override Type GetNestedType(string name, BindingFlags bindingAttr)
    {
    return _baseType.GetNestedType(name, bindingAttr);
    }

    public override Type[] GetNestedTypes(BindingFlags bindingAttr)
    {
    return _baseType.GetNestedTypes(bindingAttr);
    }

    public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
    {
    PropertyInfo[] clrProperties = _baseType.GetProperties(bindingAttr);
    if (clrProperties != null)
    {
    return clrProperties.Concat(_customProperties).ToArray();
    }
    else
    return _customProperties.ToArray();
    }

    protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
    {
    PropertyInfo propertyInfo = (from prop in GetProperties(bindingAttr) where prop.Name == name select prop).FirstOrDefault();
    if (propertyInfo == null)
    {
    // 如果没有对应的clr属性则返回自定义属性
    propertyInfo = (from prop in _customProperties where prop.Name == name select prop).FirstOrDefault();
    }
    return propertyInfo;
    }

    protected override bool HasElementTypeImpl()
    {
    throw new NotImplementedException();
    }

    public override object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
    {
    return _baseType.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
    }

    protected override bool IsArrayImpl()
    {
    throw new NotImplementedException();
    }

    protected override bool IsByRefImpl()
    {
    throw new NotImplementedException();
    }

    protected override bool IsCOMObjectImpl()
    {
    throw new NotImplementedException();
    }

    protected override bool IsPointerImpl()
    {
    throw new NotImplementedException();
    }

    protected override bool IsPrimitiveImpl()
    {
    return _baseType.IsPrimitive;
    }

    public override Module Module
    {
    get { return _baseType.Module; }
    }

    public override string Namespace
    {
    get { return _baseType.Namespace; }
    }

    public override Type UnderlyingSystemType
    {
    get { return _baseType.UnderlyingSystemType; }
    }

    public override object[] GetCustomAttributes(Type attributeType, bool inherit)
    {
    return _baseType.GetCustomAttributes(attributeType, inherit);
    }

    public override object[] GetCustomAttributes(bool inherit)
    {
    return _baseType.GetCustomAttributes(inherit);
    }

    public override bool IsDefined(Type attributeType, bool inherit)
    {
    return _baseType.IsDefined(attributeType, inherit);
    }

    public override string Name
    {
    get { return _baseType.Name; }
    }
    }

    /// <summary>
    /// 继承抽象类 PropertyInfo,以实现自定仪的 PropertyInfo
    /// </summary>
    private class CustomPropertyInfoHelper : PropertyInfo
    {
    public string _name;
    public Type _type;
    public List<Attribute> _attributes = new List<Attribute>();


    public CustomPropertyInfoHelper(string name, Type type)
    {
    _name = name;
    _type = type;
    }

    public CustomPropertyInfoHelper(string name, Type type, List<Attribute> attributes)
    {
    _name = name;
    _type = type;
    _attributes = attributes;
    }

    public override PropertyAttributes Attributes
    {
    get { throw new NotImplementedException(); }
    }

    public override bool CanRead
    {
    get { return true; }
    }

    public override bool CanWrite
    {
    get { return true; }
    }

    public override MethodInfo[] GetAccessors(bool nonPublic)
    {
    throw new NotImplementedException();
    }

    public override MethodInfo GetGetMethod(bool nonPublic)
    {
    throw new NotImplementedException();
    }

    public override ParameterInfo[] GetIndexParameters()
    {
    throw new NotImplementedException();
    }

    public override MethodInfo GetSetMethod(bool nonPublic)
    {
    throw new NotImplementedException();
    }

    public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
    {

    return obj.GetType().GetMethod("GetPropertyValue").Invoke(obj, new[] { _name });
    }

    public override Type PropertyType
    {
    get { return _type; }
    }

    public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
    {
    obj.GetType().GetMethod("SetPropertyValue").Invoke(obj, new[] { _name, value });
    }

    public override Type DeclaringType
    {
    get { throw new NotImplementedException(); }
    }

    public override object[] GetCustomAttributes(Type attributeType, bool inherit)
    {
    var attrs = from a in _attributes where a.GetType() == attributeType select a;
    return attrs.ToArray();
    }

    public override object[] GetCustomAttributes(bool inherit)
    {
    return _attributes.ToArray();
    }

    public override bool IsDefined(Type attributeType, bool inherit)
    {
    throw new NotImplementedException();
    }

    public override string Name
    {
    get { return _name; }
    }

    public override Type ReflectedType
    {
    get { throw new NotImplementedException(); }
    }

    internal List<Attribute> CustomAttributesInternal
    {
    get { return _attributes; }
    }
    }
    }
    }



    OK
    [源码下载] 

  • 相关阅读:
    【docker】更换挂载目录
    【设计】交互走查表
    MySQL常用字符串函数
    VIM_manual
    MySQL操作符
    基础SELECT实例
    MySQL字符集及校对规则的理解
    Linux命令之tar-rsync
    Linux-PATH_环境变量
    MySQL常用数据类型
  • 原文地址:https://www.cnblogs.com/webabcd/p/2397427.html
Copyright © 2020-2023  润新知