2013-03-12 100 views
2

Mvvm Light Devotees如何处理以下情况。我有几个使用它们自己的“Child”ViewModel实例的“Master”ViewModels。即Mvvm Light ViewModel With ViewModel

Child ViewModel - “OrderLineItemListViewModel”订单中订单项列表的视图模型。

Parent ViewModel - “OrderDetailViewModel”订单的视图模型。 父VIewModel - “OrderChargeViewModel”用于收取订单的视图模型。

父视图模型都需要有一个OrderLineItems列表,并且两者都可以同时打开。目前,我已经设置父ViewModel包含一个child ViewModel类型的属性,然后可以引用它。

public class ChildViewModel 
{ 
    public ChildViewModel() 
    { 
     Items = new ObservableCollection<ListItemViewModel> 
        { 
         new ListItemViewModel("One"), 
         new ListItemViewMOdel("Two") 
        } 
    } 

    public ObservableCollection<ListItemViewModel> Items {get; private set;} 
} 

public class ParentViewModel 
{ 
    public ParentViewModel() 
    { 
     ChildViewModel = new ChildViewModel(); 
    } 

    public ChildViewModel ChildViewModel {get; set;} 
} 

<Window> 
    <DataGrid ItemsSource={Binding ChildViewModel.Items} /> 
</Window> 

现在,我觉得应该有一个方式与ViewModelLocator和消息要做到这一点,但是我还没有想出一个干净的方式来做到这一点。我知道如何使用ViewModelLocator来创建ViewModels的非单例实例,所以没关系。然而,我无法弄清楚如何让父ViewModel响应子ViewModel消息并知道该消息是否来自“它的”子ViewModel,因此应该对其执行操作。

任何人对如何处理这个问题有任何建议,还是应该继续按照我的方式去做?我认为最重要的部分是现在,我有选择地使用ViewModelLocator,但不确定最终是否会直观。

回答

1

我不确定这个总数是否会回答你的问题,但是我拥有的是与你一样的嵌套视图模型。我有一个父视图/ viewmodel有一个集合(在这种情况下是一个实体框架导航属性),我希望子视图/ viewmodel与之相互作用。这样就可以在没有消息的情况下进行“互动”。例如,如果您想要将父集的集合绑定到子视图模型中的组合框,则可以这样做(请注意,父视图和子视图是usercontrols,在父视图中是内容控件绑定到子视图/视图模型):

<UserControl x:Class="EmployeeListView" 
      DataContext="{Binding EmployeeList_VM, Source={StaticResource Locator}}"/> 
    <ContentControl Name="DetailControl" DataContext="{Binding Path=Selection, Mode=TwoWay}" > 
     <ComboBox Name="cbStatus" 
      ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}},Path=DataContext.EmployeeStatus}" 
      SelectedItem="{Binding ElementName=DetailControl, Path=DataContext.employee_status}" 
      SelectedValuePath="idStatus" 
      SelectedValue="{Binding idStatus, Mode=TwoWay, ValidatesOnDataErrors=True}" 
      DisplayMemberPath="chrCode"/> 
    </ContentControl> 
</UserControl> 

我试图让它尽可能简单。请注意itemsource绑定到包含我绑定到的集合(EmployeeStatus)的祖先usercontrol datacontext。这样,您的子视图模型可以与您的父虚拟机集合/对象进行交互,而无需使用消息传递。否则,我已经使用消息传递来定位特定的视图模型,如果这是你正在寻找,但我认为上述可能更简单。

编辑: 在回答您的意见,我觉得这里的挑战是要分离的父/子的ViewModels,但在同一时间,你希望能够告诉哪些是“配对”。所以恕我直言,做到这一点的方法是创建一些类型的标志/标识符,在父视图模型和子视图模型上具有匹配的属性。我将在父视图模型的contruuctor中设置此属性,并为子视图模型具有第二个构造函数,该构造函数在其构造函数中接受此标识并设置该属性。然后,我将使用该信使来定位父视图的类型,并将该标识作为消息的参数传递。然后,我将在父视图模型中注册Messenger,以侦听目标为其“类型”的消息,并检查标识符标志/参数是否与父视图模型中的标识符匹配。

通过为子视图模型提供两个构造函数,您可以在其他位置仍使用子视图模型,而不是直接依赖父视图模型的属性类型,从而避免将它们耦合在一起。

我希望这是有道理的。你说你对这个信使很熟悉,所以我没有发表一个如何定位一个类型并给消息添加一个参数的例子,但是如果你愿意,我可以。

希望这会有所帮助。

+0

我使用Mvvm Light,如标题所示。感谢您的意见,我不认为我们正在处理相同的情况。我不想避免使用消息传递,我正在尝试使用它。我需要弄清楚如何使用ViewModelLocator来创建我的父视图模型和子视图模型(目前它只创建父视图,然后父视图手动创建它的子视图),并让父视图知道何时来自子视图的消息是*它的*孩子(反之亦然),因此它可以采取相应的行动。 – 2013-03-12 20:02:34

+0

你为什么要使用信使?它到底是什么?我发现尽可能少地使用信使是更好的,通常有更好的解决方案。对于框架问题抱歉,没有仔细阅读。 – 2013-03-12 20:09:51

+0

我想要使用管理器,这样我就可以更完全地将我的视图模型与其他视图模型分离开来,并且更完全地利用视图模型定位器。 – 2013-03-13 12:40:00