您好 我想知道这种方法是否正确,或者应该是正确的方法 我有一个MVVM模式,我有一个ListView 我的想法是,当我在列表视图中选择一个项目时,viewmodel中的一个属性会使用所选对象进行更新。 HOwever,当用户按下Intro时,我希望viewmodel做某事(打开一个新的浏览器窗口)。我做了这样的事情:
private void listView1_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
var vm = Resources["Locator"] as MainViewModel;
if (listView1.SelectedIndex != -1 && e.Key == Key.Enter)
{
vm.OpenBrowserForSelectedOffer();
}
}
但是我不知道这是否是正确完成事情的正确方法,或者是否应该做其他事情。因为在这种情况下,视图实际上是在请求视图模型(这是一个资源),也许它“对它有太多了解”,并且有更好的方法来解决这类问题。
答案 0 :(得分:3)
我假设您使用的是WPF或Silverlight。使用命令模式当然是执行UI事件触发的命令的正确方法。但是,问题在于,在您的情况下,此操作本身会对UI执行某些操作;这不是viewmodel的责任。
可以通过简单的方式解决,以便视图模型保持可测试性。使用OpenBrowserForOffer操作创建IBrowserService接口。
public void OpenBrowserForOffer(Offer offer, Action<Result> callback)
创建一个打开浏览器并显示所选商品的实现。创建另一个实现,它是一个没有UI东西的模拟实现。
然后从viewmodel中注入一个IBrowserService实例,并使用它打开浏览器或执行模拟逻辑,具体取决于从实际应用程序或测试运行。
请注意,在视图中,您可以使用DataContext来获取视图模型。
答案 1 :(得分:2)
OpenBrowserForOffer
做什么并不是很清楚,但我的猜测是它为该优惠打开了一个新的浏览器窗口(使用例如Process.Start()
),对吗?
如果是这样,那么我认为viewmodel可以完全正常来处理它,因为它是业务逻辑的一部分。
视图知道或假设有关视图模型的内容没有问题,它已经做了(因为你绑定了它的属性)。
正如另一个答案所示,您可以通过查看DataContext轻松获取视图的当前视图模型。在我需要代码访问viewmodel的视图中,为方便起见,我通常会实现两个属性:
private YourViewModelType ViewModel
{
get { return DataContext as YourViewModelType; }
}
private bool HasViewModel { get { return ViewModel != null; } }
答案 2 :(得分:1)
在Viewmodel中使用绑定到listView的KeyDown-Event / Command的命令,并在viewmodel中的命令中移动代码,voilá,你清除了mvvm模式。