zoukankan      html  css  js  c++  java
  • 稳扎稳打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
    [源码下载] 

  • 相关阅读:
    CF 461B Appleman and Tree
    POJ 1821 Fence
    NOIP 2012 开车旅行
    CF 494B Obsessive String
    BZOJ2337 XOR和路径
    CF 24D Broken robot
    POJ 1952 BUY LOW, BUY LOWER
    SPOJ NAPTIME Naptime
    POJ 3585
    CF 453B Little Pony and Harmony Chest
  • 原文地址:https://www.cnblogs.com/webabcd/p/2397427.html
Copyright © 2011-2022 走看看