// 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
根据x1e0 f1 a,ViewModel不知道View,因此这是不可接受的。要与ViewModel View交互,可能会触发命令,也可以使用绑定。此外,您不应将特定于UI的东西(如BusyIndicator)移动到ViewModel级别。 请提供更多关于您的具体用例的详细信息-当您想要调用视图的方法时,以及此方法的作用。
6条答案
按热度按时间siv3szwd1#
我(也许还有其他人?)在MVVM方面的困难在于理解一件简单的事情:View知道ViewModel。我使用绑定和命令,但它们是简单的
xaml
中的strings
。由于在运行时安全解析(安全意味着您可以输入错误,但软件不会崩溃),这使得视图与视图模型 * 解耦 *(至少在编译时)。我一直在寻找保持这种解耦的解决方案,例如,行为。事实上,您可以直接访问视图模型,它通常是一个
DataContext
窗口/用户控件:知道了这一点,使用事件可能是从视图模型调用视图方法的最佳方式,因为视图模型不知道是否有订阅者,它只是触发该事件,而事件可以被视图或其他视图模型使用。
wdebmtf22#
您可以在View中这样做(代码隐藏)。
它强制转换为ViewModel要实现的接口,这样您就不会被限制为一个特定的ViewModel类型。
gt0wga4j3#
根据x1e0 f1 a,ViewModel不知道View,因此这是不可接受的。要与ViewModel View交互,可能会触发命令,也可以使用绑定。此外,您不应将特定于UI的东西(如BusyIndicator)移动到ViewModel级别。
请提供更多关于您的具体用例的详细信息-当您想要调用视图的方法时,以及此方法的作用。
tuwxkamq4#
假设您在我的登录视图的代码背后有一个方法,如果登录失败,该方法通过将焦点带到密码条目来更新UI,那么从ViewModel触发此方法的最简单和最通用的方法是使用Action delegates。
正如您在this sample中所看到的,在您的服务确定登录失败并且您希望Password Entry获得焦点的情况下,您所需要添加的全部内容是ViewModel中的两行代码和View中的一个操作处理程序。
视图模型代码:
public Action<bool> OnLoginFailed { get; set; }
和OnLoginFailed?.Invoke(true);
查看代码:
更新:I wrote an article以更详细地解释这一点
xn1cxnb45#
我看到了你对上面答案的回复,你说你想让你的视图模型检索数据,然后告诉你的视图停止忙碌指示器。
我不确定我的解决方案是否是最好的解决方案,但你可以给予一下,也许有人可以纠正我的错误。
因此,从视图中,您可以调用ViewModel中的一个方法来开始阅读数据集,对吗?在这个方法中,您可以传递一个委托(指向视图中存在的一个方法),当ViewModel从服务器读取完数据集时,触发与视图中的方法相链接的委托(从视图模型中),该委托可以停止忙碌指示符。
所以在你看来
当你调用ViewModel来读取数据集时
这样称呼它:
它将StopBusyIndicator方法作为委托传递,您可以在ReadDataSet的末尾调用该方法。
高温加热
camsedfj6#
您可以编写一个接受数据传输对象的操作类。在DTO中,添加一个名为“View”的属性,并将其分配给当前视图。通过视图代码隐藏中的控制器调用操作,取消DTO的装箱,现在您就可以完全控制操作类中的视图了。
如果你真的想在你的模型中这样做,只需在你的模型中创建一个带有“View”类型参数的方法,然后执行它,传入当前视图。