5

到目前为止,我对我的应用程序从无处不在的典型点击事件处理程序到完成 GUI 解耦的过渡方式感到非常满意。现在我遇到了一些我无法弄清楚的事情,它与我希望我的 GUI 弹出的窗口有关,它需要显示来自模型的信息。

我想我的问题的简短版本是,在 MVVM 中是否绝对禁止允许模型引用 ViewModel?这是我的场景:我有一组 LED 可以非常快速地循环通过 RGB 值。我希望我的 GUI 中的一个窗口通过与 ViewModel 的数据绑定来显示更新的颜色。我让 Window + UserControl 在测试应用程序中与模型 ViewModel 一起正常工作,但现在我必须将此 Window 放入我的真实应用程序中。

我正在运行的特定模式模拟硬件正在做什么。当我命令模型循环显示颜色时,它会启动一个线程来更改必要的类成员变量的值。

我当前的 MVVM 实现基本上是一直在轮询。为了让其他 LED 在其他地方更新,我运行了一个线程,该线程调用 ViewModel 中的一个函数。这会更新属性,因此 GUI 会自动更新,因为我正在使用数据绑定。我的 LED 示例中的问题是模拟颜色序列是在线程中完成的,所以如果我需要对值进行 ViewModel 轮询,由于 LED 变量的过度锁定,它可能会很慢。

因此,我希望有人可以推荐另一种解决此问题的方法。到目前为止,我唯一能真正想到的就是让 Window 数据上下文成为 LEDViewModel,然后还将 LEDViewModel 传递给 Model。然后当我调用 RGB 循环函数时,它可以根据需要更改必要的 ViewModel 属性,我根本不需要使用任何锁定。

这有意义吗?任何建议将不胜感激。

4

3 回答 3

7

您是否尝试过INotifyPropertyChanged在模型上实现接口?

在我看来,这应该表现得足够好。当模型上的颜色状态发生变化时,您可以触发PropertyChanged事件,从该通知更新视图模型状态,并通过视图模型上的绑定来更新视图。

于 2010-01-20T21:22:22.947 回答
3

为什么不在您的应用程序的某种消息代理上使用事件?

最简单的方法是在 MVVMFoundation 中使用 Messenger:http: //mvvmfoundation.codeplex.com/

这方面的一个例子是:

public class MyHardwareModel
{
     private void OnHardwareLEDChanged() // or whatever
     {
          SharedMessages.Messenger.NotifyColleagues(SharedMessages.LEDCHANGED);
     }
}

然后在您的视图模型中,当它启动时,您会在该视图模型的实例处于活动状态时注册这些消息的通知:

public class MyHardwareViewModel
{
     public MyHardwareViewModel()
     {
          SharedMessages.Messenger.Register(SharedMessages.LEDCHANGED, UpdateLeds);
     }

     private void UpdateLeds()
     {
          //Update ObservableCollection here.
     }
}

消息中介/代理模式在这些情况下非常有用,不仅如此。MVVMFoundation 中内置的 Messenger 非常强大……在我的示例中,我使用了非常通用的消息,但您可以发送更多带有参数的类型化消息。

如果您使用称为 EventAggregator 的功能,Prism / Composite Application Guidance 中内置了一个类似的功能。它以类似的方式使用。

希望这可以帮助。

于 2010-01-21T04:39:18.913 回答
0

一个简单的方法是定期执行轮询,比如每 50 毫秒。这可以很容易地使用计时器完成,并且比来自线程的持续轮询消耗更少的资源。50ms 似乎是一个合理的间隔,即使你的 LED 实际上循环更快,因为用户无论如何都没有时间看到颜色变化......

于 2010-01-20T21:49:39.547 回答