标准属性有效,但依赖属性无效;t

本文关键字:属性 无效 依赖 有效 标准 | 更新日期: 2023-09-27 18:25:16

我有以下代码,它可以工作:

public DataTemplate ItemTemplate
{
    get { return _list.ItemTemplate; }
    set { _list.ItemTemplate = value; }
}

我有我想要的代码,但它不起作用。甚至setter从未被调用:

public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(MyUserControl));
public DataTemplate ItemTemplate
{
    get { return (DataTemplate)GetValue(ItemTemplateProperty); }
    set
    {
        _list.ItemTemplate = value;
        SetValue(ItemTemplateProperty, value);
    }
}

它在XAML中的使用:

<Window.Resources>
    <DataTemplate x:Key="ItemTemplate">
        <TextBlock Text="{Binding Path=Name}"/>
    </DataTemplate>
</Window.Resources>
<local:MyUserControl ItemTemplate="{StaticResource ItemTemplate}"/>

为什么标准属性有效,而依赖属性无效?

标准属性有效,但依赖属性无效;t

使用依赖属性,.Net正在做一些不明显的事情:它直接访问由ItemTemplateProperty标识的依赖属性,而不是使用您声明的getset方法。在这种情况下,唯一的区别是您的_list.ItemTemplate = value;从未运行过。

当您使用依赖属性时,getter和setter应该只包含通常的内容。其他任何事情都会令人困惑,因为WPF在使用该属性时会绕过它们。

如果需要将_list.ItemTemplate设置为该值,则应使用其他DependencyProperty.Register重载附加一个静态PropertyChangedCallback。例如

private static void OnItemTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
    var uc = (MyUserControl)d;
    uc._list.ItemTemplate = (DataTemplate)e.NewValue;
}
DependencyProperty从不调用"Set"方法,而是必须在创建依赖属性语句时查找PropertyChanged事件处理程序。
public static readonly DependencyProperty ItemTemplateProperty = 
   DependencyProperty.Register(
        "ItemTemplate", 
         typeof(DataTemplate), 
         typeof(MyUserControl),
         new FrameworkPropertyMetadata( 
             null, 
             new PropertyChangedCallback(ItemTemplateChanged) ));
public DataTemplate ItemTemplate
{
    get { return (DataTemplate)GetValue(ItemTemplateProperty); }
    set
    {
        _list.ItemTemplate = value;
        SetValue(ItemTemplateProperty, value);
    }
}
public static void ItemTemplateChanged(
   DependencyObject sender, 
   DependencyPropertyChangedEventArgs e){
   ((MyUserControl)sender).OnItemTemplateChanged(e);
}
protected void OnItemTemplateChanged(DependencyPropertyChangedEventArgs e){
    // you write your code here..
}