Reputation: 25414
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?
Upvotes: 7
Views: 857
Reputation: 39916
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..
}
Upvotes: 2
Reputation: 56536
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;
}
Upvotes: 7