WPF DataBinding与MVVM和用户控件

时间:2014-09-11 19:53:34

标签: wpf mvvm user-controls

我们说我有一个客户窗口,显示有关客户的信息,如姓名,地址和电话号码。在底部有一个他们订单的DataGrid。当然,Customer有一个Orders属性,所以如果你使用MVVM,你只需要设置:

ItemsSource = "{Binding Customer.Orders}"

但是,现在让我们说数据网格现在是用户控件的一部分,用户控件还包括用于编辑/添加/删除订单的控件。我想在多个地方使用同一组控件,我希望编辑/添加/删除Order对象的所有逻辑都封装在用户控件中。因为我想使用命令而不是事件处理程序,我希望用户控件拥有自己的视图模型。

现在问题是:如何将订单从客户视图模型传递到订单用户控件的视图模型?因为Orders用户控件将绑定到视图模型,所以我不能说:

<local:OrdersUserControl DataContext="{Binding Customer.Orders}" />

因为用户控件拥有自己的视图模型。它会期望在那里看到Customer.Orders,当然它不是。

我想这是一种鸡肉或鸡蛋的情况。

我们非常感谢您的帮助。

亚伦

2 个答案:

答案 0 :(得分:7)

现在我的每周“不要那样做”答案......

我不能说...因为用户控件拥有自己的视图模型。

我说的是

为UserControl创建ViewModel是代码味道。

由于这种气味,你遇到了这个问题,这应该表明你做错了

解决方案是抛弃为UserControl构建的VM。如果它包含业务逻辑,则应将其移动到另一个ViewModel中的适当位置。

您应该将UserControl视为一个更复杂的控件。 TextBox是否有自己的ViewModel?您可以将您的 VM的属性绑定到控件的Text属性,控件会在其UI中显示您的文本。

MVVM并不意味着没有代码隐藏。将用户控件的UI逻辑放在代码隐藏中。如果它太复杂以至于您需要在用户控件中使用业务逻辑,那么这表明它太过笼统。将其分解为两个或更多。

将MVCon中的UserControl想象成这样 - 对于每个模型,您都有一个UserControl,它旨在将该模型中的数据呈现给用户。您可以在任何想要向用户显示该模型的地方使用它。它需要一个按钮吗?在UserControl上公开ICommand属性,并让您的业务逻辑绑定到它。您的业​​务逻辑是否需要知道内部发生的事情?添加路由事件。

通常情况下,在WPF中,如果你发现自己在问某些为什么会有什么伤害,那是因为你不应该这样做。

答案 1 :(得分:0)

有许多方法可以给猫皮肤。我这样做的方法是让我的CustomerViewModel具有OrdersViewModel类型的属性。然后在构造函数中(或者在您设置客户的任何地方)让它设置&#34; OrdersContext&#34;使用新的OrdersViewModel传入customer.orders。

<强> XAML:

<local:OrdersUserControl DataContext="{Binding OrdersContext}" />

ViewModel:

public CustomerViewModel(Customer customer)
{
    Customer = customer;
    OrdersContext = new OrdersViewModel(customer.Orders);
}