CustomTypeDescriptor'System.Reflection.TargetException'WindowsBase.dll

时间:2016-06-20 12:14:25

标签: c# wpf

我在基类中有一个简单的CustomTypeDescriptor实现。 出于某种原因,我得到System.Reflection.TargetException。 这个实现有问题吗?

#region DynamicPropertyObjectBase
/// <summary>
/// Base classs for objects supporting dynamic properties.
/// </summary>
public abstract class DynamicPropertyObjectBase : PropertyChangedBase,
    IDynamicPropertyObject
{
    #region CONSTRUCTOR
    public DynamicPropertyObjectBase() : base()
    { }
    #endregion

    #region FIELDS
    private Dictionary<string, PropertyDescriptor> propertyStore = new Dictionary<string, PropertyDescriptor>();
    #endregion

    #region FUNCTIONS

    public void SetPropertyValue<T>(string propertyName, T propertyValue)
    {
        if (string.IsNullOrWhiteSpace(propertyName))
            throw new ArgumentNullException(nameof(propertyName));

        var properties = this.GetProperties()
                                .Cast<PropertyDescriptor>()
                                .Where(prop => prop.Name.Equals(propertyName));

        if (properties == null || properties.Count() != 1)
            throw new ArgumentNullException(nameof(propertyName));

        var property = properties.First();
        property.SetValue(this, propertyValue);

        RaisePropertyChanged(propertyName);
    }

    public T GetPropertyValue<T>(string propertyName)
    {
        if (string.IsNullOrWhiteSpace(propertyName))
            throw new ArgumentNullException(nameof(propertyName));

        var properties = this.GetProperties()
                            .Cast<PropertyDescriptor>()
                            .Where(prop => prop.Name.Equals(propertyName));

        if (properties == null || properties.Count() != 1)
            throw new ArgumentNullException(nameof(propertyName));

        var property = properties.First();
        return (T)property.GetValue(this);
    }

    public PropertyDescriptor AddProperty<T, U>(string propertyName) where U : PropertyChangedBase
    {
        return this.AddProperty(propertyName, new DynamicPropertyDescriptor<T>(propertyName, typeof(U)));
    }

    public PropertyDescriptor AddProperty<T>(string propertyName)
    {
        return this.AddProperty(propertyName, new DynamicPropertyDescriptor<T>(propertyName, this.GetType()));
    }

    private PropertyDescriptor AddProperty(string propertyName, PropertyDescriptor customProperty)
    {
        if (string.IsNullOrWhiteSpace(propertyName))
            throw new ArgumentNullException(nameof(propertyName));

        if (customProperty == null)
            throw new ArgumentNullException(nameof(customProperty));

        //will throw if other entry with same name already exist
        propertyStore.Add(propertyName, customProperty);

        //add value change handler
        customProperty.AddValueChanged(this, (o, e) => { RaisePropertyChanged(propertyName); });

        //return back to caller
        return customProperty;
    }

    #endregion

    #region OVERRIDES

    public override PropertyDescriptorCollection GetProperties()
    {
        var properties = new PropertyDescriptorCollection(TypeDescriptor.GetProperties(this,true)
            .Cast<PropertyDescriptor>()
            .Union(propertyStore.Values)
            .ToArray());

        return properties;
    }

    public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
    {
        var properties = new PropertyDescriptorCollection(TypeDescriptor.GetProperties(this,attributes,true)
           .Cast<PropertyDescriptor>()
           .Union(propertyStore.Values)
           .ToArray());

        return properties;
    }

    public override AttributeCollection GetAttributes()
    {
        return TypeDescriptor.GetAttributes(this, true);
    }

    public override object GetEditor(Type editorBaseType)
    {
        return TypeDescriptor.GetEditor(this, editorBaseType, true);
    }

    public override string GetClassName()
    {
        return TypeDescriptor.GetClassName(this, true);
    }

    public override string GetComponentName()
    {
        return TypeDescriptor.GetComponentName(this, true);
    }

    public override TypeConverter GetConverter()
    {
        return TypeDescriptor.GetConverter(this, true);
    }

    public override PropertyDescriptor GetDefaultProperty()
    {
        return TypeDescriptor.GetDefaultProperty(this, true);
    }

    public override EventDescriptor GetDefaultEvent()
    {
        return TypeDescriptor.GetDefaultEvent(this, true);
    }

    public override EventDescriptorCollection GetEvents()
    {
        return TypeDescriptor.GetEvents(this, true);
    }

    public override EventDescriptorCollection GetEvents(Attribute[] attributes)
    {
        return TypeDescriptor.GetEvents(this, attributes, true);
    }

    public override object GetPropertyOwner(PropertyDescriptor pd)
    {
        return this;
    }

    #endregion
} 
#endregion

对于大多数情况,一切正常,但在某些情况下,如果有一个集合包含从此实现派生的类,则会抛出TargetException,例如,如果您尝试清除集合。

0 个答案:

没有答案