从ViewModel调用View的CodeBehind中的方法?

我的View中的代码背后有一个方法(这个方法对我的UI做了一些事情)。

无论如何,我想从我的ViewModel中触发这个方法。 怎么可以这样做?

我(也许是其他人?)MVVM的难点在于理解一件简单的事情: View了解ViewModel 。 我使用的是绑定和命令,但它们是xaml中的简单strings 。 由于在运行时安全解析(安全意味着你可以做错字,但软件不会崩溃)这使得视图视图模型分离 (至少在编译时)。 我一直在寻找解决方案,以保持这种脱钩,例如,行为。

事实是,您可以直接访问视图模型,这通常是窗口/用户控件的DataContext

 var vm = (MyViewModel)this.DataContext; 

知道这一点,使用事件可能是从视图模型调用视图方法的最佳方法,因为视图模型不知道是否有订阅者,它只是触发该事件和事件可以被视图或其他视图模型使用。

 // define in the view model public delegate void MyEventAction(string someParameter, ...); public event MyEventAction MyEvent; // rise event when you need to MyEvent?.Invoke("123", ...); // in the view var vm = (MyViewModel)DataContext; vm.MyEvent += (someParameter, ...) => ... // do something 

根据MVVM模式, ViewModel并不知道View,所以这是不可接受的。 要与ViewModel View进行交互,可以触发命令,也可以使用绑定。 此外,您不应该将特定于UI的东西(如BusyIndi​​cator)移动到ViewModel级别。

请提供更多有关您的具体用例的详细信息 – 当您想要调用View的方法以及此方法的用途时。

你可以在View(后面的代码)中这样做。

它转换为由ViewModel实现的接口,因此您不会受限于一种特定的ViewModel类型。

  // CONSTRUCTOR public SomeView() { InitializeComponent(); DataContextChanged += DataContextChangedHandler; } void DataContextChangedHandler(object sender, DependencyPropertyChangedEventArgs e) { var viewModel = e.NewValue as IInterfaceToBeImplementedByViewModel; if (viewModel != null) { viewModel.SomeEvent += (sender, args) => { someMethod(); } } } 

我看到你回复上面的答案,你说你希望你的ViewModel检索数据然后告诉你的视图停止繁忙指示。

我不确定我的解决方案是否是最佳解决方案,但你可以尝试一下,如果我错了,也许有人可以纠正。

因此,从您的角度来看,您将从ViewModel调用一个方法来开始读取数据集,对吗? 在此方法中,您可以传递委托(指向视图中存在的方法),当ViewModel完成从服务器读取数据集时,触发链接到视图中的方法的委托(来自您的viewmodel)可以停止忙碌的指标。

所以在你看来你有

 void StopBusyIndicator() { this.BusyIndicator.IsBusy = false; } 

当您调用ViewModel读取数据集时

这样叫:

 ViewModel.ReadDataSet( ()= >StopBusyIndicator) 

它将StopBusyIndi​​cator方法作为委托传递,您可以在ReadDataSet的末尾调用它。

HTH

您可以编写一个接受数据传输对象的操作类。 在DTO中,添加一个名为“View”的属性并为其指定当前视图。 通过控制器从视图的代码隐藏中调用操作,取消打开DTO,现在您可以完全控制操作类中的视图。

如果您真的想在模型中执行此操作,只需在模型中使用“View”类型参数创建方法并执行它,并传入当前视图。