7

我有以下代码,它有效:

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}"/>

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

4

2 回答 2

7

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

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

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

private static void OnItemTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
    var uc = (MyUserControl)d;
    uc._list.ItemTemplate = (DataTemplate)e.NewValue;
}
于 2013-07-29T13:19:52.570 回答
2

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..
}
于 2013-07-29T13:21:47.127 回答