我们可以在不从 DependencyObject 继承的 class 中实现依赖项 属性 吗?如果是,有什么区别?
Can we implement dependency property in a class that does not inherit from DependencyObject? If yes, what is the difference?
我们能否在不继承自 DependencyObject
的 class 中实现依赖项 属性?如果是的话有什么区别?
是的,你可以。这是 Attached 属性 的变体。来自 How to Create an Attached Property:
If your class is defining the attached property strictly for use on other types, then the class does not have to derive from DependencyObject
. But you do need to derive from DependencyObject
if you follow the overall WPF model of having your attached property also be a dependency property.
不同之处在于您如何定义附加 属性。而不是 Register
, you have to use the RegisterAttached
方法,您必须使用以下命名约定将 get 和 set 访问器定义为静态方法,其中 PropertyName
是附加的 属性.
的名称
public static object GetPropertyName(object target)
public static void SetPropertyName(object target, object value)
让我们看一个简单的例子。假设您要创建一个并排显示图像和文本的按钮。不幸的是,一个 Button
只有一个 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);
}
}
现在您可以将此 属性 附加到视图中的按钮以定义图像路径。这里附加的 属性 的不同之处在于您使用其所有者类型 IconButtonProperties
.
在不同的类型 (Button
) 上定义它
<Button ContentTemplate="{StaticResource ImageTextContentTemplate}"
local:IconButtonProperties.Source="Resources/MyImage.png"
Content="Click me!"/>
最后一个重大差异显示在使用附加 属性 和 Binding
的数据模板中。绑定到附加的 属性 时,您必须 put the property in parentheses.
<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 中的可扩展性和绑定来说是无价的。有关一般附加属性的更多信息,您可以参考文档:
我们能否在不继承自 DependencyObject
的 class 中实现依赖项 属性?如果是的话有什么区别?
是的,你可以。这是 Attached 属性 的变体。来自 How to Create an Attached Property:
If your class is defining the attached property strictly for use on other types, then the class does not have to derive from
DependencyObject
. But you do need to derive fromDependencyObject
if you follow the overall WPF model of having your attached property also be a dependency property.
不同之处在于您如何定义附加 属性。而不是 Register
, you have to use the RegisterAttached
方法,您必须使用以下命名约定将 get 和 set 访问器定义为静态方法,其中 PropertyName
是附加的 属性.
public static object GetPropertyName(object target)
public static void SetPropertyName(object target, object value)
让我们看一个简单的例子。假设您要创建一个并排显示图像和文本的按钮。不幸的是,一个 Button
只有一个 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);
}
}
现在您可以将此 属性 附加到视图中的按钮以定义图像路径。这里附加的 属性 的不同之处在于您使用其所有者类型 IconButtonProperties
.
Button
) 上定义它
<Button ContentTemplate="{StaticResource ImageTextContentTemplate}"
local:IconButtonProperties.Source="Resources/MyImage.png"
Content="Click me!"/>
最后一个重大差异显示在使用附加 属性 和 Binding
的数据模板中。绑定到附加的 属性 时,您必须 put the property in parentheses.
<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 中的可扩展性和绑定来说是无价的。有关一般附加属性的更多信息,您可以参考文档: