I have a very simple example of a DependencyProperty
I've registered on a UserControl which is not quite working as expected.
I am binding this property to a DP (called Test) in MainWindow which seems to be firing the OnPropertyChanged
events every time it is changed, but the DependencyProperty
in my UserControl that is the target of this binding only seems to get notified the first time this property is changed.
Here is what I'm trying to do in code:
My UserControl:
public partial class UserControl1 : UserControl
{
public static readonly DependencyProperty ShowCategoriesProperty =
DependencyProperty.Register("ShowCategories", typeof(bool), typeof(UserControl1), new FrameworkPropertyMetadata(false, OnShowsCategoriesChanged));
public UserControl1()
{
InitializeComponent();
}
public bool ShowCategories
{
get
{
return (bool)GetValue(ShowCategoriesProperty);
}
set
{
SetValue(ShowCategoriesProperty, value);
}
}
private static void OnShowsCategoriesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//this callback is only ever hit once when I expect 3 hits...
((UserControl1)d).ShowCategories = (bool)e.NewValue;
}
}
MainWindow.xaml.cs
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
Test = true; //this call changes default value of our DP and OnShowsCategoriesChanged is called correctly in my UserControl
Test = false; //these following calls do nothing!! (here is where my issue is)
Test = true;
}
private bool test;
public bool Test
{
get { return test; }
set
{
test = value;
OnPropertyChanged("Test");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string property)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(property));
}
}
}
MainWindow.xaml
<Window x:Class="Binding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:uc="clr-namespace:Binding"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="350" Width="525">
<Grid>
<uc:UserControl1 ShowCategories="{Binding Test}" />
</Grid>
</Window>
The problem is that you're setting the ShowCategories
value to itself:
((UserControl1)d).ShowCategories = (bool)e.NewValue;
This line is useless, since the value of ShowCategories
has already been modified. That's why you're in the property changed callback in the first place. At first glance, this could be seen as a no-op: after all, you're simply setting a property value to its current value, which in WPF doesn't raise any change.
However, since the binding isn't two-way, changing the property value overwrites the binding. That's why there is no more callback raised. Simply remove the assignment in the callback and you're done.
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