bit*_*onk 0 wpf dependency-properties attached-properties
我刚刚发现自己可以做到以下几点:
var button = new Button();
button.SetValue(TextBlock.TextProperty, "text");
var text = (string)button.GetValue(TextBlock.TextProperty); // text is "text"
Run Code Online (Sandbox Code Playgroud)
尽管上面的示例有些不切实际,但它确实表明我可以将常规依赖项属性附加到另一个对象上。它不必是附加的属性(TextBlock.TextProperty
未在中注册)DependencyProperty.RegisterAttached()
。
这就提出了一个问题,为什么首先要有附加属性?我现在看到的唯一区别是,我无法在XAML中附加常规依赖项属性。就是这样。还有其他区别吗?
更新:
为了更加清楚,下面的代码可以正常工作,并且从最终用户的角度来看,它看起来非常接近附加属性:
public static class AttachedPropertyDeclarer
{
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text",
typeof(string),
typeof(Button),
new PropertyMetadata(default(string),OnTextChanged));
private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// do something when text changed
}
}
...
button.SetValue(AttachedPropertyDeclarer.TextProperty, "text");
var text = (string)button.GetValue(AttachedPropertyDeclarer.TextProperty);
Run Code Online (Sandbox Code Playgroud)
将此与附加的属性方式进行比较:
public static class AttachedPropertyDeclarer
{
public static readonly DependencyProperty TextProperty = DependencyProperty.RegisterAttached(
"Text",
typeof(string),
typeof(AttachedPropertyDeclarer),
new PropertyMetadata(default(string),OnTextChanged));
private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// do something when text changed
}
}
Run Code Online (Sandbox Code Playgroud)
此处与附加属性的唯一有效区别是,我必须声明type的所有者,Button
而在附加属性中通常为AttachedPropertyDeclarer
。但这仅在需要更改事件处理程序(即OnTextChanged
)的情况下需要执行。
关于您的示例,您没有像您所说的那样将常规依赖项属性附加到另一个对象上。您的代码所能实现的就是将一个string
值Dictionary
与对您的对象的引用一起存储。但这并不能使它成为附加属性-重要的是,您不能直接string
从该值访问该值Button
,因为上没有Text
属性Button
。
您的代码实际上实际上与此类似:
Dictionary<object, object> values2 = new Dictionary<object, object>();
var button = new Button();
values2.Add(button, "text");
string text = values2[button].ToString();
Run Code Online (Sandbox Code Playgroud)
现在回答您的问题:
声明附加属性的主要原因是为了向未声明的类型添加属性,从而扩展其功能。
一个很好的例子是将一个SelectedItems
属性添加到ItemsControl
或ListBox
类。为此,我们扩展了该类的当前功能或默认功能。另一个很好的例子是声明一个附加属性,该属性会自动将添加的项目显示在视图中(还是在ItemsControl
或ListBox
类中)。
更新>>>
根据您的评论,您似乎拒绝接受我概述的差异...您说:
从最终用户的角度看,实际上没有什么区别,只是我不能在XAML中使用它。
首先,你不认为这是一个巨大的区别?..你将无法使用它的数据的一个开始绑定。此外,您一直说可以将属性附加到您尚未使用声明的类型上DependencyProperty
,但是您100%不正确。您可以直接在代码和 XAML中引用附加属性,而不能在XAML 或代码中直接引用正在调用附加属性的内容。
您要做的只是在a中存储一个值Dictionary
,您当然不需要a的开销DependencyProperty
。这样做与声明附加属性之间确实没有可比之处。从MSDN上的“ 附加属性概述”页面:
如果有必要为除定义类之外的其他类提供属性设置机制,则可以创建一个附加属性。
请注意以下部分:属性设置机制
将值添加到Dictionary
中不是属性设置机制。同样,您也失去了在Style
s,Animation
s,Trigger
s等中使用伪装的附加属性的能力。
为了一劳永逸地澄清这种情况,您可以开发一个简单的测试项目。IList SelectedItems
为ListBox
我提到的实现一个附加属性(您可以在此找到在线教程),然后使用假装的附加属性(如果可能的话)进行相同的操作。两者之间在开发简单性上的差异将清楚地向您显示为什么应使用附加属性而不是常规属性DependencyProperty
。