【发布时间】:2020-10-29 16:19:14
【问题描述】:
假设我有一个代表我的模型的第三方后端 [C# .NET Standard] 库;该库纯粹用作数据处理后端工具。 显然没有 GUI,只提供了一些公共只读寄存器,以允许其他父/拥有代码观察这些寄存器的状态。举个简单的例子:
public class MyModel
{
public int MyVariable { get; private set; }
public List<int> MyCollection { get; private set; }
...
}
现在我想提供一个 WPF 应用程序作为视图面板/仪表板,以便用户可以在监视器上查看实时情况;我选择了 MVVM 方法。
第一个问题是:假设 Model 应该保持不变,而不使其适应 ViewModel 是否是正确的设计方法(忘记 Model 是我实际上不拥有的代码的第三方库)?如何有效且正确地编写 ViewModel 以便它可以从 Model 中提取/检索这些寄存器? 我经历了一个基于时间的更新选项(每秒从 Model 重新读取这些寄存器),老实说,这似乎有点低效;我不知道如何从 ViewModel 端拦截模型变量更改或模型集合更改。
然后,让我们暂时放弃我没有库代码的约束,并考虑我可以修改模型(再次,它是一个正确的设计吗?)。我会让MyModel 实现INotifyPropertyChanged 并将List<int> MyCollection 更改为ObservableCollection<int> MyCollection,以便我可以拦截数据更改并绑定以在屏幕上更新。但是当CollectionChanged 事件被触发时,我陷入了Dispatcher 问题。 由于 Model 无法访问 Dispatcher (.NET Standard),我如何执行集合更新?如何抑制 Model 触发的 CollectionChanged 并从 Dispatcher 中的 ViewModel 触发它?
我已经通过Dispatcher 转发解决方案,但我再次认为这是错误的,没有正确编码:
public delegate void DispatcherService(Action action);
public class MyModel
{
public int MyVariable { get; private set; }
public List<int> MyList { get; private set; }
public event DispatcherService MyDispatcherService;
public void AddElementToMyList(int element)
{
MyDispatcherService?.Invoke(() => MyList.Add(element));
}
}
public class MyViewModel
{
private MyModel _myModel;
public int MyModelMyVariable { get { return _myModel.MyVariable; } }
public List<int> MyModelMyCollection { get { return _myModel.MyCollection; } }
public MyViewModel(MyModel myModel)
{
_myModel = myModel;
_myModel.MyDispatcherService += ((action) => { Application.Current.Dispatcher.Invoke(action); });
}
}
【问题讨论】:
-
有什么办法可以说明寄存器列表中的某些内容发生了变化吗?正如所描述的,tgese 听起来像是你只能轮询的东西。这些整数从秒到秒有多少变化?巴秒处理多少?您的视图是否会变得模糊,或者某个项目会在一秒钟内发生变化,还是什么?
标签: c# wpf mvvm binding dispatcher