简体   繁体   中英

Standard property works, but dependency property doesn't in WPF

I have the following code behind, which works:

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

And I have the code, that I want to have, but it doesn't work. Even setter is never invoked:

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);
    }
}

The use of that is in XAML:

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

<local:MyUserControl ItemTemplate="{StaticResource ItemTemplate}"/>

Why the standard property works and dependency property doesn't?

With the dependency property, .Net is doing something that's not obvious: it's accessing the dependency property identified by ItemTemplateProperty directly instead of using the get and set methods that you declared. The only difference, in this case, is that your _list.ItemTemplate = value; is never run.

When you use dependency properties, your getters and setters should only contain the usual things . Anything else will end up being confusing because WPF bypasses them when it uses the property.

If you need to set _list.ItemTemplate to the value, you should attach a static PropertyChangedCallback using the other DependencyProperty.Register overload . Eg

private static void OnItemTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
    var uc = (MyUserControl)d;
    uc._list.ItemTemplate = (DataTemplate)e.NewValue;
}

DependencyProperty never invokes "Set" method, instead you will have to look for PropertyChanged event handler within creation of dependency property statement.

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..
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM