根据
this answer
我不需要费心去为层叠结构上冒泡的NotifyPropertyChanges而烦恼,但我仍然无法让它与这样一个(简化的测试)结构一起工作:
数据保持类
public class TestNotifyChanged : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _Test = "default";
public string Test
{
get
{
return _Test;
}
set
{
if(_Test!=value)
{
_Test = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Test"));
}
}
}
}
使用该测试类和测试属性的ViewModel:
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private TestNotifyChanged tnc = new TestNotifyChanged(); // only to init, otherwise VS screams at me
public ViewModel(TestNotifyChanged tnc)
{
tnc = tnc; // getting an instance of TestNotifyChanged from "Master" passed in, which hopefully will be replaces by a singleton class.
}
private string _Test;
public string Test
{
get
{
return tnc.Test; // this might be the crucial part!?
}
set
{
if (_Test != value) // never hits that, as I would expect, but you never know..
{
_Test = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Test")); // of course also never hit, as expected
}
}
}
}
最后是我的主窗口
public partial class MainWindow : Window
{
TestNotifyChanged tnc;
public MainWindow()
{
InitializeComponent();
tnc = new TestNotifyChanged();
DataContext = new ViewModel(tnc); // pass in my Test-Object that has the Values.
}
private void ButtonGet_Click(object sender, RoutedEventArgs e)
{
tnc.Test = "new Value";
MessageBox.Show($"{tnc.Test}"); // got "new Value" here!
}
}
在xaml中,除了这个按钮之外,我还有一个简单的文本块,它绑定到ViewModel的测试属性:
<TextBlock x:Name="OutputId" Text="{Binding Path=Test, Mode=OneWay}"/>
现在发生了什么:
我想实现的目标:
当我直接设置测试值时,我可以很容易地使这个工作
在视图模型上
-但这似乎不对,而且与我认为我可以构建应用程序/代码的想法相去甚远。未来的目标是要有一个单例(静态的我想不通)的“记录存储”,它拥有大部分的数据(并且从一个API、本地数据库或者仅仅从内存中获取,如果这些都完成了的话)
所以问题是:
为什么NotifyPropertyChange没有冒泡到View/ViewModel?
或者还有什么我看不到的问题?
我读过
INotifyPropertyChanged bubbling in class hierarchy
和
What is a good way to bubble up INotifyPropertyChanged events through ViewModel properties with MVVM?
和
https://docs.microsoft.com/en-us/dotnet/framework/winforms/how-to-implement-the-inotifypropertychanged-interface
和
OnPropertyChange called but not taking any effect on UI
这些问题大多也很古老。。。
编辑:
我试过“矿工”的建议:
// made tnc public in ViewModel
public TestNotifyChanged tnc = new TestNotifyChanged();
// changed Binding directly to that (and it's Property):
<TextBlock x:Name="OutputId" Text="{Binding Path=tnc.Test, Mode=OneWay}"/>
不幸的是,现在我甚至没有得到默认值,所以我一定误解了smth。
编辑2
:
我在第一次编辑中做错了一件事:
// this isn't recognized as bindable parameter:
public TestNotifyChanged tnc = new TestNotifyChanged();
// it instead has to be
public TestNotifyChanged tnc { get; }
我成功了
TNC
,删除了本地
Test
参数,直接绑定到
Path=TNC.Test
所以我明白了,财产的变化
不要
按照我的期望/想法,最好直接绑定到嵌套对象。