View是否可以订阅ViewModel CLR事件?

发布于 2024-09-01 00:27:05 字数 132 浏览 2 评论 0原文

有时,视图模型需要发出通知,视图应该处理并执行某些操作作为响应,尤其是。当这些无法建模为属性和属性更改通知时。

MVVM Light 中是否有任何内容可以允许视图侦听事件并通过声明性 Xaml 标记将视图模型通知转换为用户界面操作?

Sometimes a view model needs to raise notifications, that a view should handle and do something in response, esp. when these can't be modeled as properties and property change notifications.

Anything in MVVM Light that can allow the view to listen to events and translate view model notifications into user interface actions via declarative Xaml markup?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

左耳近心 2024-09-08 00:27:05

就我个人而言,我发现从虚拟机引发事件并在视图中捕获它们的技术在某些情况下是可以接受的。不过,在这种情况下,我通常更喜欢使用 Messenger,特别是如果您需要自定义事件参数(因为声明新的事件参数类和新委托需要大量工作)。

此外,事件处理程序是视图和视图模型之间的紧密耦合,而您通常更喜欢松散耦合,但如果您意识到这一事实和后果,那么为什么不......

另一种技术(例如导航,对话框等)是声明一个带有您需要的方法的接口(例如带有 AskConfirmation 和 ShowMessage 方法的 IDialogService)。然后让一个类实现该接口(可以是 MainWindow/MainPage 本身)并将其传递给 ViewModel(例如在调用 InitializeComponent 之后立即在 View 的构造函数中)。在VM中,需要时调用这些方法。这样做的优点是非常容易测试(只需模拟 IDialogService 并检查是否调用了方法)。

我通常会根据各种因素在 Messenger 和 IDialogService 之间切换。不过,我最近倾向于支持基于接口的方法,因为它更容易测试(但 Messenger 也很容易测试,所以 YMMV)。

干杯,
洛朗

Personally I find the technique of raising events from the VM and catching them in the view acceptable in certain circumstances. I typically prefer to work with the Messenger for such occasions though, especially if you need custom event args (because it is quite a lot of work to declare a new event args class and a new delegate).

Also, the event handler is a tight coupling between view and viewmodel, while you would typically prefer a loose coupling, but if you are aware of that fact and of the consequences, then why not...

Another technique (for example for navigation, dialogs etc) is to declare an interface with the methods you need (for example IDialogService with AskConfirmation and ShowMessage methods). Then have a class implement that interface (that can be the MainWindow/MainPage itself) and pass it to the ViewModel (for example in the View's constructor right after InitializeComponent was called). In the VM, call these methods when needed. This has the advantage of being quite easy to test (simply mock the IDialogService and check that the methods are called).

I typically move between Messenger and IDialogService depending on various factors. I tend to favor the interface based approach lately though, because it is a little easier to test (but the Messenger is quite testable too so YMMV).

Cheers,
Laurent

兔小萌 2024-09-08 00:27:05

在“纯”MVVM 解决方案中,唯一应该将 View 连接到 ViewModel 的是绑定。没有什么可以阻止您将 DataContext 转换为 ViewModel 类型并在视图中挂钩事件,但这有点违背了使用 MVVM 方法的目的。作为替代方案,尝试重新思考为什么您认为需要向视图引发事件:

  • 需要显示弹出窗口?当视图模型将通知对象“插入”到绑定集合中时,可以使用某种类型的“弹出通知”绑定列表和适当的模板来在视图上创建弹出窗口。
  • 需要强制打开下拉菜单或一些类似的 UI 操作?将 UI 上的适当属性绑定到视图模型属性,将模式设置为双向,然后在视图模型上进行适当的设置。

等等等等

In a "pure" MVVM solution, the only thing that should connect the View to the ViewModel is Bindings. There is nothing stopping you from casting your DataContext to your ViewModel type and hooking an event in the view, but it kind of defeats the purpose of using the MVVM approach. As an alternative, try to rethink of why you think you need to raise an event to the view:

  • Need to display a popup? Some variety of bound list of "popup notifications" can be used, with a proper template, to create popups on the view as the viewmodel "inserts" notification objects into the bound collection.
  • Need to force a drop down open, or some similar UI action? Bind the appropriate property on the UI to a view model property, set the mode to two-way, and set as appropriate on the view model.

etc, etc.

萤火眠眠 2024-09-08 00:27:05

你是对的,有时 ViewModel 需要与 View 进行通信。实现此目的的一种方法是 ViewModel 引发 View 侦听的 CLR 事件。这可以在视图的代码隐藏中完成。

MVVM 并不是要消除视图的代码隐藏!这是关于关注点分离和通过单元测试提高可测试性。

在 ViewModel 和 View 之间进行通信的另一种方法是引入接口 (IView)。有关此方法的更多信息,请访问 WPF 应用程序框架 (WAF) 项目地点。

You are right that sometimes the ViewModel needs to communicate with the View. One way to do this is that the ViewModel raises a CLR event which the View listens to. This can be done in the code-behind of the View.

MVVM is not about eliminating the code-behind of the Views! It’s about separation of concerns and improving the testability with unit tests.

Another way to enable the communication between the ViewModel and the View is by introducing an interface (IView). More information about this approach can be found on the WPF Application Framework (WAF) project site.

白芷 2024-09-08 00:27:05

MVVMLight 中确实有一种受支持的技术,用于处理从 ViewModel 到 View 发送消息。查看 GalaSoft.MvvmLight.Messaging 命名空间的内部。有一种比下面的示例更好的发送 dialod 消息的方法,但这只是一个简单的示例。

示例

视图模型

public MainPageViewModel()
{
    Messenger.Default.Send("Payment");
}

视图

public MainPage()
{
    Messenger.Default.Register<string>(this, DialogRequested);
}

private DialogRequested(string message)
{
    MessageBox.Show(message);
}

There is indeed a supported technique in MVVMLight for handling sending Messages from your ViewModel to your View. Look inside the GalaSoft.MvvmLight.Messaging namespace. There is a better way to send dialod messages then the below sample, however this is just a quick example.

Example

ViewModel

public MainPageViewModel()
{
    Messenger.Default.Send("Payment");
}

View

public MainPage()
{
    Messenger.Default.Register<string>(this, DialogRequested);
}

private DialogRequested(string message)
{
    MessageBox.Show(message);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文