如何在WPF MVVM应用程序中处理可绑定的应用程序级变量?

3
我正在使用MVVM模式编写一个相当大规模的WPF桌面应用程序。我一直陷入困境,无法使我的公共属性在更新它的视图之外的其他视图中更新。
我有一个包含ContentControl的RibbonWindow MainView,该ContentControl根据用户的选择一次显示其余视图。我有一个BaseViewModel类,所有ViewModel都扩展该类。除其他事项外,此类公开了INotifyPropertyChanged接口,并包含CommonDataStore类型的静态属性。此类还实现了INotifyPropertyChanged接口,并包含每个ViewModel都可用的属性。
尽管我可以从任何ViewModel访问并成功更新CommonDataStore属性,但问题是WPF Framework仅通知当前视图中已更改的属性。因此,尽管常见值已在其他ViewModel中更新,但其关联的视图不会更新。
我的应用程序中的一个示例是登录屏幕:随着用户登录,我的LogInView会使用来自数据库的新信息(即全名)进行更新,但MainView中的用户详细信息不会更新。
阅读了一些其他帖子后,我也尝试将CommonDataStore类实现为Singleton,但这并没有帮助。我也可以从MainViewModel将对此公共数据对象的引用传递给每个ViewModel的构造函数,但我不确定这是否是正确的方法。
我还发现,在WPF中,静态属性有点像常量值。似乎它们只读取一次值。
总之,我的尝试都失败了。我想知道标准方法是什么?特别是,我需要能够绑定到常见属性,并在更改任何常见值时更新所有ViewModel和Views。非常感谢您的帮助。提前致谢。
编辑>>真的吗?没有人在MVVM WPF应用程序中使用应用程序范围变量吗?
我现在已删除Common属性声明的静态部分,并仅将其副本逐个传递给每个ViewModel。这似乎有效,但我真的想知道其他人如何处理这种情况。请简单回答,让我知道您如何组织此应用程序范围数据。

请发布一些代码...你是如何编写绑定的? - Thomas Levesque
通常的方式是:Text="{Binding Common.CurrentEmployee.Name}"Common 是基类中的属性,而 CurrentEmployee 则是 CommonDataStore 类中的属性。我无法发布所有相关代码 - 太多了。我想问其他人是如何实现这个的,而不是要求特定修复我的代码。 - Sheridan
好的,但是Common在基类的所有实例之间共享吗? - Thomas Levesque
只是出于好奇,你是否绑定了Mode=TwoWay?你的模型对象实现了INotify吗?还是只有VM中的属性实现了? - Scott Silvi
Common属性是static的,所以是的,它在所有的ViewModel之间是共享的。我的视图中不需要进行Two-Way绑定...登录使用一个调用LogInViewModel中方法的Command。该方法将用户登录并从数据库中检索用户详细信息。它更新了Common对象,但只有LogInView中的详细信息被更新。CommonDataStore中的所有属性都调用了INotifyPropertyChanged系统,但是BaseViewModel中的Common属性不能调用,因为它是静态的。我还将其包装在一个非静态方法中,并调用了Notify...但没有帮助。 - Sheridan
你需要发布一些代码示例,否则这将是大海捞针。 - kevindaub
2个回答

0

你有考虑过实现观察者模式吗?我们使用IObservableIObserver实现了这一点。这里描述了“IObservable/IObserver开发模型”的内容:

IObservable/IObserver开发模型提供了一种替代使用输入和输出适配器作为事件源和汇的生产者和消费者的方法。该模型基于IObservable/IObserver设计模式,其中观察者是希望在另一个对象的状态更改时得到通知的任何对象,而可观察对象是任何可能感兴趣的对象,另一个对象可以在其中注册兴趣。例如,在发布-订阅应用程序中,可观察对象是发布者,观察者是订阅者对象。有关更多信息,请参见MSDN上的“探索观察者设计模式”。


感谢您的回复。虽然很有趣,但我认为观察者模式不是我想要的。 - Sheridan

0

我曾经做过类似你描述的事情。我有一个叫做SecurityContext的类,保存着一些应用程序范围的数据。当应用程序启动时,会创建一个实例,然后将该实例通过依赖注入传递给所有ViewModel的构造函数。我为ViewModels提供了一个基类,通过常规的实例属性(实现了INotifyPropertyChanged接口)来暴露这个对象。


谢谢你的回复,Mike。我很高兴得到一些反馈,证明我所做的事情并没有违反任何MVVM原则。 - Sheridan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接