我们可以在不继承自的类中实现依赖属性DependencyObject
吗?如果是,有什么区别?
1 回答
是的你可以。这是Attached Property的变体。从如何创建附加属性:
如果您的类严格定义附加属性以用于其他类型,则该类不必派生自
DependencyObject
.DependencyObject
但是,如果您遵循将附加属性也作为依赖属性的整体 WPF 模型,则确实需要从中派生。
不同之处在于您如何定义附加属性。而不是Register
,您必须使用该RegisterAttached
方法,并且您必须使用以下命名约定将 get 和 set 访问器定义为静态方法,其中PropertyName
是附加属性的名称。
public static object GetPropertyName(object target)
public static void SetPropertyName(object target, object value)
让我们看一个简单的例子。假设您要创建一个并排显示图像和文本的按钮。不幸的是, aButton
只有一个Content
. 由于您现在不想创建自定义控件,因此您尝试通过为要显示的图像路径创建内容模板和附加属性来解决此问题。
public static class IconButtonProperties
{
public static readonly DependencyProperty SourceProperty = DependencyProperty.RegisterAttached(
"Source", typeof(string), typeof(IconButtonProperties));
public static void SetSource(UIElement element, string value)
{
element.SetValue(SourceProperty, value);
}
public static string GetSource(UIElement element)
{
return (string) element.GetValue(SourceProperty);
}
}
现在您可以将此属性附加到视图中的按钮以定义图像路径。此处附加属性的不同之处在于您Button
使用其所有者类型在不同的类型 ()上定义它IconButtonProperties
。
<Button ContentTemplate="{StaticResource ImageTextContentTemplate}"
local:IconButtonProperties.Source="Resources/MyImage.png"
Content="Click me!"/>
最后一个重大区别显示在数据模板中,该模板使用带有Binding
. 绑定到附加属性时,您必须将属性放在括号中。
<DataTemplate x:Key="ImageTextContentTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
Source="{Binding (local:IconButtonProperties.Source), RelativeSource={RelativeSource AncestorType={x:Type Button}}}"/>
<TextBlock Grid.Column="1"
VerticalAlignment="Center"
Margin="5, 0, 0, 0"
Text="{Binding}"/>
</Grid>
</DataTemplate>
如您所见,附加属性对于 WPF 中的可扩展性和绑定非常重要。有关一般附加属性的更多信息,您可以参考文档: