我对WPF和MVVM都很陌生,而且我试图解决这个问题......
我在其后面实现了前面提到的 CustomerSearchView 和 CustomerSearchViewModel 。 ViewModel具有当前所选项的属性。
我实现了另一个视图,使用户能够查看和编辑客户( CustomerEditView )。当然,这个视图有一个自己的ViewModel - CustomerEditViewModel 。
现在,我想让用户在搜索视图中选择一个客户,然后该客户应该在详细信息视图中可见(并准备编辑)。 注意:很可能,将来我会在应用程序中使用单独的 CustomerSearchView 的多个窗口或页面。因此,将一般事件发送给中央事件处理程序似乎对我来说是错误的方法。
在坚持MVVM的同时实现这一目标的正确方法是什么?
答案 0 :(得分:2)
我认为你必须有某种一般的CustomerViewModel
。
假设父视图模型有一个属性:
public CustomerViewModel SelectedCustomer { /* INPC clutter */ }
为每个视图提供该类型的依赖项属性,并绑定它们。
<local:CustomerSearchView
SelectedCustomer="{Binding SelectedCustomer}"
/>
<local:CustomerEditView
EditedCustomer="{Binding SelectedCustomer}"
/>
CustomerSearchView
将通过绑定或其他内容更新其SelectedCustomer
。如果你不清楚如何用你所拥有的东西做到这一点,我们可以进入。
CustomerEditView
会有这样的属性:
#region EditCustomer Property
public CustomerViewModel EditCustomer
{
get { return (CustomerViewModel)GetValue(EditCustomerProperty); }
set { SetValue(EditCustomerProperty, value); }
}
public static readonly DependencyProperty EditCustomerProperty =
DependencyProperty.Register(nameof(EditCustomer), typeof(CustomerViewModel), typeof(CustomerEditView),
new FrameworkPropertyMetadata(null, EditCustomer_PropertyChanged));
protected static void EditCustomer_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as MainWindow).OnEditCustomerChanged(e.OldValue);
}
private void OnEditCustomerChanged(object oldValue)
{
// Or maybe your CustomerEditViewModel can acquire a new customer
// to edit in some other way.
DataContext = new CustomerEditViewModel(EditCustomer);
}
#endregion EditCustomer Property
但这不是我们在应用程序中执行此操作的方式。对于我们来说,我们的父视图模型将具有CustomerSearchViewModel CustomerSearch {...}
属性和CustomerEditViewModel CustomerEdit {...}
属性,以及上面的SelectedCustomer
属性。在CustomerEditViewModel
更改时,父视图模型将负责告知SelectedCustomer
要编辑的客户。
然后我们在资源字典中有一些隐含的数据窗口,它们被合并到主视图中:
<DataTemplate DataType="{vm:CustomerSearchViewModel}">
<vw:CustomerSearchView />
</DataTemplate>
<DataTemplate DataType="{vm:CustomerEditViewModel}">
<vw:CustomerEditView />
</DataTemplate>
然后在包含搜索和编辑视图的父视图中:
<ContentControl Content="{Binding CustomerSearch}" />
<ContentControl Content="{Binding CustomerEdit}" />
使用这种“viewmodel-first”方法,视图永远不会提供自己的视图模型。另一方面,这会使父视图模型稍微涉及UI设计问题,例如客户编辑器所在的位置。
答案 1 :(得分:-1)
有多种方法可以做到,但我使用的方法是让一个父ViewModel能够保存对两个ViewModel的引用。
然后,这位家长有责任通知每个孩子另一个孩子的变化。
另一种方法是使用服务类,该服务类将保存数据并为修改此数据提供一些事件(这些事件将在您的服务属性&#39; setters中调用)。 您的两个ViewModel将订阅他们感兴趣的事件(因此属性),并做出相应的反应。
对于您的应用程序的未来,如果您不希望中央ViewModel处理所有事情,我会采用服务方式。
编辑:如果downvote是因为我没有显示代码,我也没有显示任何一个,所以我不能做更多的事情。