我試圖使用[TypeDescriptionProviderAttribute]
爲了給我的類定製一個類型描述符。這工作,但是當我實現INotifyPropertyChanged
WPF似乎忽略了自定義類型描述符,並直接爲CLR屬性(如果存在)。以下是一段代碼,稍後我將粘貼完整示例:當INotifyPropertyChanged被實現時,爲什麼WPF似乎繞過了TypeDescriptionProviderAttribute?
//[TypeDescriptionProvider(typeof(MyProvider))]
class MyModel : Object
//, INotifyPropertyChanged
//, ICustomTypeDescriptor
{
public string TheProperty { get { return "CLR - TheProperty"; } }
我將TextBlock綁定到TheProperty。當我...
讓一切評論
我看到的 - 如預期 「CLR利人」。
使用
[TypeDescriptionProvider]
我看到的 - 如預期 「MyPropertyDescriptor利人」。
使用
ICustomTypeDescriptor
我看到的 - 如預期 「MyPropertyDescriptor利人」。
使用
ICustomTypeDescriptor
和INotifyPropertyChanged
我看到的 - 如預期 「MyPropertyDescriptor利人」。
使用
[TypeDescriptionProvider]
和INotifyPropertyChanged
我看到 「CLR - 利人」。 這是爲什麼?奇怪的是,自定義屬性沒有 CLR屬性正常顯示。我的自定義類型描述符還會返回一個「MyPropertyDescriptor - AnotherProperty」,它可以在所有情況下都起作用,因爲沒有定義CLR
AnotherProperty
。
綜上所述,鑑於此XAML預期,因爲該模型沒有一個名爲 「AnotherProperty」 一個CLR屬性
<StackPanel>
<TextBlock Text="{Binding TheProperty}" />
<TextBlock Text="{Binding AnotherProperty}" />
</StackPanel>
AnotherProperty
始終有效。 TheProperty
按預期工作除了當[TypeDescriptionProvider]
和INotifyPropertyChanged
都使用。
以下是完整的代碼。這是一個有點長,但大部分是不相關的,它只是由System.ComponentModel
public partial class TestWindow : Window
{
public TestWindow()
{
InitializeComponent();
DataContext = new MyModel();
}
}
//[TypeDescriptionProvider(typeof(MyProvider))]
class MyModel : Object
//, INotifyPropertyChanged
//, ICustomTypeDescriptor
{
public string TheProperty { get { return "CLR - TheProperty"; } }
public event PropertyChangedEventHandler PropertyChanged;
public AttributeCollection GetAttributes()
{
return TypeDescriptor.GetAttributes(this);
}
public string GetClassName()
{
return TypeDescriptor.GetClassName(this);
}
public string GetComponentName()
{
return TypeDescriptor.GetComponentName(this);
}
public TypeConverter GetConverter()
{
return TypeDescriptor.GetConverter(this);
}
public EventDescriptor GetDefaultEvent()
{
return TypeDescriptor.GetDefaultEvent(this);
}
public PropertyDescriptor GetDefaultProperty()
{
return TypeDescriptor.GetDefaultProperty(this);
}
public object GetEditor(Type editorBaseType)
{
return TypeDescriptor.GetEditor(this, editorBaseType);
}
public EventDescriptorCollection GetEvents(Attribute[] attributes)
{
return TypeDescriptor.GetEvents(this, attributes);
}
public EventDescriptorCollection GetEvents()
{
return TypeDescriptor.GetEvents(this);
}
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return TypeDescriptor.GetProperties(this, attributes);
}
public PropertyDescriptorCollection GetProperties()
{
return MyTypeDescriptor.GetCustomProperties();
}
public object GetPropertyOwner(PropertyDescriptor pd)
{
return this;
}
}
class MyProvider : TypeDescriptionProvider
{
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
return new MyTypeDescriptor();
}
}
class MyTypeDescriptor : CustomTypeDescriptor
{
public override PropertyDescriptorCollection GetProperties()
{
return GetCustomProperties();
}
public static PropertyDescriptorCollection GetCustomProperties()
{
return new PropertyDescriptorCollection(
new[] {
new MyPropertyDescriptor("TheProperty"),
new MyPropertyDescriptor("AnotherProperty")
});
}
}
class MyPropertyDescriptor : PropertyDescriptor
{
public MyPropertyDescriptor(string propName)
: base(propName, null)
{
}
public override bool CanResetValue(object component)
{
return false;
}
public override Type ComponentType
{
get { return typeof(MyModel); }
}
public override object GetValue(object component)
{
return "MyPropertyDescriptor - " + Name;
}
public override bool IsReadOnly
{
get { return true; }
}
public override Type PropertyType
{
get { return typeof(string); }
}
public override void ResetValue(object component)
{
throw new InvalidOperationException("cannot reset value");
}
public override void SetValue(object component, object value)
{
throw new InvalidOperationException("property is readonly");
}
public override bool ShouldSerializeValue(object component)
{
return true;
}
}
當我試圖找出問題背後的原因(以及解決方案以及......)時,我很想知道您究竟在這裏實現了什麼目標?動態屬性? –
@AngelWPF - 用幾句話來描述並不容易,但是當我在一兩天內寫出描述時,我會發佈一個鏈接。 –