我有一个WPF控件应该很容易(重新)使用。为此,我有一个自定义类型,包含控件应该表示的所有设置,并通过DependencyProperty绑定它。
但是,每当我更改控件中的一个成员时,父控件都会获取成员中的更改(通过其他方式进行评估时),但PropertyChanged-Callback永远不会在父控件中触发。
public class Setting
{
public int Prop {get;set;}
//Other Properties, Constructor & Copy Constructor, etc.
public override bool Equals(object obj)
{
if (!(obj is Setting other)) return false;
return Prop == other.Prop;
}
}
public class SettingControl : UserControl, INotifyPropertyChanged
{
public static readonly DependencyProperty SettingProperty = DependencyProperty.Register
(nameof(Settings), typeof(Setting), typeof(SettingControl),
new PropertyMetadata(default(Setting), OnValuePropertyChanged));
public Setting Settings
{
get => (Setting)GetValue(SettingProperty);
set
{
SetValue(SettingProperty, value);
OnPropertyChanged(nameof(Settings));
}
}
public int Prop
{
get => ((Setting)GetValue(SettingProperty))?.Prop ?? 0;
set
{
//Does not work:
var temp = (Setting)GetValue(SettingProperty);
temp.Prop = value;
Settings = temp;
OnPropertyChanged(nameof(Prop));
//Does not work:
Settings.Prop = value;
OnPropertyChanged(nameof(Prop));
OnPropertyChanged(nameof(Settings));
//**Does work**, and triggers the OnSettingChanged in the parent control,
//but is simply not great memory usage
Settings = new Setting(Settings){ Prop = value };
OnPropertyChanged(nameof(Prop));
}
}
}
//Relevant snippet from parent Control ViewModel:
public static readonly DependencyProperty SettingProperty =
DependencyProperty.Register(nameof(Settings), typeof(Setting), typeof(ControlViewModel),
new PropertyMetadata(default(Setting), (d, e) => ((ControlViewModel)d).OnSettingChanged()));
//OnSettingChanged() is never called
public Setting Settings
{
get => (Setting)GetValue(SettingProperty);
set //Set is never called when the member properties are changed
{
SetValue(SettingProperty, value);
OnPropertyChanged(nameof(Settings));
}
}
//Relevant snippet from parent xaml:
<local:SettingControl Width="300"
Settings="{Binding Path=Settings, Mode=TwoWay}"/>
// UpdateSourceTrigger=PropertyChanged doesn't help here either
当然,一个明显的解决方案是将Setting
类包装到SettingViewModel
中,或者将其实现为ViewModel本身(小测试无论如何都没有显示结果)。然而,这会使控件的使用更加困难,并且在某种程度上打破MVVM(已经超过这个)。 Setting
类中还有一些用于序列化的XML内容,我不想搞砸。
我注意到的一件事是,如果Equals
中的Setting
函数被编码为始终返回true
两种设置通常不起作用的成员属性的方式,突然工作并触发所期望的行为。
先谢谢。