2011-04-17 51 views
3

我有一个返回类型为Party的数组的服务。党有两个亚型,人员和组织。我正在使用视图模型在我的WPF应用程序(Prism,MVVM)中使用此服务。在这个视图模型的构造函数中,我填充了一个可观察的类型派对集合:根据对象类型将视图注入到ItemsControl中

public PhoneBookViewModel(IPhoneBookService phoneBookProxy) 
{ 
    _phoneBookProxy = phoneBookProxy; 

    var parties = _phoneBookProxy.GetAllParties(); 
    _parties = new ObservableCollection<Party>(parties.ToList()); 
} 

到目前为止这么好。在我的PhoneBookView中,我有一个绑定到这个集合的ItemsControl。在这个控件中,我想通过使用另一个视图(及其视图模型)渲染每个聚会。所以,当党类型的人,注射PersonView和党的对象传递给PersonViewModel的构造函数,当党的组织类型,渲染OrganizationView,等等...你的图片(或?)。

但我不能想出如何在XAML做到这一点。有任何想法吗? 这可能不是最好的做法,所以如果你能推荐更好的方法,请赐教:-)

谢谢!

回答

1

允许从朝向所述模型的视图检查此:


让我们假设我们有2种不同类型的视图,1型视图模型的:

ViewA - >内的创建项目控件使用DataTempate/DataTemplateSelector,绑定到ViewModelA

ViewB - >使用DataTempate/DataTemplateSelector在项目控件中创建,绑定到ViewModelA

如果两个视图绑定到同一个视图模型,你最终会得到同样的观点。


允许与2种不同类型的视图和2种不同类型的视图模型的再试:

ViewA - 使用DataTempate/DataTemplateSelector,绑定到ViewModelA CONTROL>一个项目内创建 - >绑定到MODELA

ViewB - >创建使用DataTempate/DataTemplateSelector,绑定到ViewModelB控制一个项目内 - >绑定到ModelB

这是可能的。现在


,如果你的模型视图的模型和模式是这样的(伪代码):

public PhoneBookViewModel 
{ 
    public PhoneBookViewModel() 
    { 
     _parties = new ObservalbeCollection<PartyViewModel>(); 
    } 

    private PhoneBook _dataContext; 

    // This is the property the VM uses to access the model 
    public PhoneBook DataContext 
    { 
     get { return _dataContext; } 
     set 
     { 
      if (_dataContext != null) 
      { 
       _dataContext.Parties.CollectionChanged -= OnModelPartiesChanged; 
      } 
      _dataContext = value; 
      if (_dataContext != null) 
      { 
       _dataContext.Parties.CollectionChanged += OnModelPartiesChanged; 
      } 
     } 
    } 

    private ObservableCollection<PartyViewModel> _parties; 

    // This is the property the view uses to access the collection of VM parties 
    public ObservableCollection<PartyViewModel> PartiesViewModels { get { return _parties; } } 

    private void OnModelPartiesChanged(...) 
    { 
     // Add/remove VMs to/from PartiesViewModels here 
    } 
} 

// Model 
public PhoneBook 
{ 
    public PhoneBook() 
    { 
     _parties = new ObservalbeCollection<Party>(); 
    } 

    private ObservableCollection<Party> _parties; 

    // This is the property the VM uses to access the model's parties 
    public ObservableCollection<Party> Parties { get { return _parties; } } 
} 

public PersonViewModel : PartyViewModel 
{ 
    new Person DataContext { get; set; } 
} 

public PartyViewModel 
{ 
    public Party DataContext { get; set; } 
} 

那么你会得到正确类型的虚拟机的每个模型项目, 视图将被绑定到VM项目,而不是模型项目。


查看的的DataTemplates:

<DataTemplate x:Target={x:Type myVmNamespace:PersonViewModel}"> 
    <PersonView/> 
</DataTemplate> 

<DataTemplate x:Target={x:Type myVmNamespace:GroupViewModel}"> 
    <GroupView/> 
</DataTemplate> 

查看的ItemsControl的:

<!-- Bind to Parties property of PhoneBookVM --> 
<!-- Uses datatemplates for items --> 
<ListView ItemsSource={Binding Parties}"/> 
+0

我没有详细介绍所有的管道细节(例如集合后面的只读字段,以便将OnCollectionChanged注册到正确的集合)。但是这种方法确实很好(多次使用过)。 – 2011-04-17 15:17:37

+0

这对我来说没什么意义:-) PhoneBookViewModel中的PhoneBook DataContext是什么,它与两个PartyViewModel有什么关系?我不明白。 – 2011-04-17 17:23:26

+0

添加了更多详细信息。基本上,虚拟机连接到M的方式与V连接到虚拟机的方式类似。 – 2011-04-17 17:39:48

0

配置为您的数据类型来呈现XAML数据模板。

+0

怎么样?你将如何将参数传递给视图模型的构造函数? – 2011-04-17 17:18:51

0

如果您使用棱镜和MVVM那么你绑定命令添加到您的ItemsControl与各方。

该命令的类型为DelegateCommand<Party>。里面的命令被执行代表,这将是这样的:

private void PartyNavigate(Party party) 

只是检查方的任何子类型,并在您RegionManager具体查看的区域叫RequestNavigate

这将成为一个问题,你如何传递实际的上下文,你可以看看Prism附带的MVVM RI,它有一个非常好的方式,以StateHandler的形式,或者你可以建立自己的集中的DataManager,您可以在这里保存这些事情的状态,以及从WebServices获得的缓存内容等。在使用WPF和WCF构建智能客户端两年后,我可以告诉您最终需要构建自己的DataManager,如果您已经在使用EntityFramework并且您从EDM中生成大部分数据,那么这并不是什么大问题。

0

Your ItemsControlSourceSource的收藏由PhoneBookViewModel填充。所以剩下的唯一事情就是告诉WPF应该如何呈现这个集合的每个项目。这可以通过创建DataTemplate轻松实现。

<DataTemplate DataType="{x:Type PersonViewModel}"> 
    <MyPersonView/> 
</DataTemplate> 
+0

是的,但我需要通过一个特定的实例的意见。我怎样才能做到这一点? – 2011-04-26 17:25:43

相关问题