I’m developing a WPF desktop application, utilizing MVVM framework. I have an enum and a class defined as follows:
public enum eTypes { A, B };
public class MyClass
{
public eTypes MemberEnum { get; set; }
}
In my Model:
public class Model : INotifyPropertyChanged
{
public MyClass Stiffness { get; } // This must be read-only, since it's actually linked to a dictionary that's expected not to be changed
private int _num;
public int Num
{
get => _num;
set
{
_num = value;
Stiffness.MemberEnum = A; // Changed
OnPropertyChanged(nameof(Stiffness));
}
}
public void OnPropertyChanged([CallerMemberName]string propertyName = null, bool includeEntirePropChanged = true)
{
PropertyChanged?. Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
Then, there is an custom UserControl at the View:
public partial class PropertyGrid : UserControl
{
public static readonly DependencyProperty RowListProperty =
DependencyProperty.Register(
"PropertyList",
typeof(MyClass), typeof(PropertyGrid),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnPropsListChanged))
private static void OnPropsListChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{ // Desired operations }
public MyClass PropertyList
{
get
{
return (GetValue(RowListProperty) as IRFCProperty);
}
set
{
SetValue(RowListProperty, value);
}
}
}
And finally, the .xaml code for Views that uses the UserControl (DataContext correctly set to instance of Model)
<PropertyGrid PropertyList="{Binding Stiffness, UpdateSourceTrigger=PropertyChanged}" />
The desired behaviour would be: when the user changes Model’s Num => Stiffness’s MemberEnum is changed => OnPropertyChanged(nameof(Stiffness)) => Stiffness is binded with PropertyList in the View, which is backed by RowListProperty => OnPropsListChanged should be invoked, which updates the view.
However, OnPropsListChanged never gets called, because the DependencyProperty’s “effective value changed” will indicate that the Stiffness object is the same (even though we changed one of its member variables). The only work around for me now is to create a Clone for the object that’s returned from Stiffness’s get, then call the OnPropertyChanged(nameof(Stiffness)), which then works. However, this is very much prone to error (the provided code is made simple to illustrate my point).
I tried adding FrameworkPropertyMetadataOptions.AffectsRender flag to the declaration of RowListProperty, but it doens’t work, as well as FrameworkPropertyMetadataOptions.BindsTwoWayByDefault (because Stiffness is read-only)
Is there a way to have an option to edit the ‘effective value’ check of DependencyObject’s SetValue?
You are only changing a property of
MyClassbut not theStiffnessproperty value/instance itself.In other words, because there is no assignment to the
PropertyListproperty the property changed callback is not invoked.What you should do is to observe the new
PropertyListvalue for property changes: