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?
DependencyProperty has to be static (Class level) because when we create multiple objects of the class which has that property and want to refer the default value for that property the value has to come from that static instance of DependencyProperty.
Dependency properties and the WPF property system extend property functionality by providing a type that backs a property, as an alternative to the standard pattern of backing a property with a private field. The name of this type is DependencyProperty.
Dependency properties are stored in a dictionary of key/value pairs which is provided by the DependencyObject class. It also saves a lot of memory because it stores the property when changed. It can be bound in XAML as well.
The Normal CLR property and the dependency property look quite similar but the dependency property is more powerful and has more features. In WPF, dependency properties are used in Animation, Styles, Triggers, Templates, Validation, Data Binding, Layout etc.
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. E.g.
private static void OnItemTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var uc = (MyUserControl)d;
uc._list.ItemTemplate = (DataTemplate)e.NewValue;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With