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

问题描述 投票:0回答:7

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

无论如何,我想从我的 ViewModel 触发这个方法。这怎么能做到呢?

c# wpf xamarin mvvm uwp
7个回答
41
投票

我(也许还有其他人?)使用 MVVM 的困难在于理解一件简单的事情:View 了解 ViewModel。我使用的是绑定和命令,但它们很简单

strings
in
xaml
。由于运行时的安全解析(安全意味着您可以犯错,但软件不会崩溃),这使得视图与视图模型“解耦”(至少在编译时)。我一直在寻找解决方案来保持这种解耦,例如行为。 事实是,您可以直接访问视图模型,这通常是窗口/用户控件的

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



10
投票

它转换为由 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(); } } }



5
投票
MVVM 模式

ViewModel 不知道 View,所以这是不可接受的。要与 ViewModel 交互,视图可以触发命令,也可以使用绑定。此外,您不应该将特定于 UI 的内容(例如 BusyIndicator)移至 ViewModel 级别。 请提供有关您的具体用例的更多详细信息 - 当您想要调用 View 的方法以及该方法的作用时。


4
投票
Action delegates

正如您在

此示例

中所看到的,您需要添加的所有内容(您的服务确定登录失败并且您希望密码输入获得焦点)是 ViewModel 中的两行代码和一个操作处理程序你的观点。 ViewModel代码:

活动声明:
    public Action<bool> OnLoginFailed { get; set; }
  • &
    然后简单地,当需要时,执行这个
  • OnLoginFailed?.Invoke(true);
  • 
    
  • 查看代码:

ViewModel.OnLoginFailed = ((obj) => { PasswordEntry.Focus(); });

更新:我
写了一篇文章

更详细地解释了这一点


0
投票

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

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

所以在你看来你有

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

当您调用 ViewModel 来读取数据集时,

这样称呼它:

ViewModel.ReadDataSet( ()= >StopBusyIndicator)

它将传递 StopBusyIndicator 方法作为委托,您可以在 ReadDataSet 末尾调用该方法。

HTH


0
投票

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


0
投票
	
© www.soinside.com 2019 - 2024. All rights reserved.