根据对象类型将视图注入ItemsControl [英] Inject views into ItemsControl depending on object type

查看:169
本文介绍了根据对象类型将视图注入ItemsControl的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个返回Party类型数组的服务。党有两个子类型,人和组织。我正在使用视图模型在我的WPF应用程序(Prism,MVVM)中使用此服务。在此视图模型的构造函数中,我填充了Party类型的可观察集合:

I have a service returning an array of type Party. Party has two subtypes, Person and Organization. I’m consuming this service in my WPF application (Prism, MVVM) from a view model. In the constructor of this view model I populate an observable collection of type Party:

public PhoneBookViewModel(IPhoneBookService phoneBookProxy)
{
    _phoneBookProxy = phoneBookProxy;

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

到目前为止一切顺利。在我的PhoneBookView中,我有一个ItemsControl绑定到这个集合。在此控件中,我想使用另一个View(及其视图模型)渲染每个Party。所以当Party是Person类型时,注入PersonView并将Party对象传递给PersonViewModel的构造函数,当Party类型为Organization时,渲染OrganizationView,等等......你得到图片(或?)。

So far so good. In my PhoneBookView I have an ItemsControl that binds to this collection. In this control I want to render each Party by using another View (and its view model). So when Party is of type Person, inject PersonView and pass the Party object to the constructor of the PersonViewModel, and when Party is of type Organization, render OrganizationView, and so on... You get the picture (or?).

但我无法弄清楚如何在XAML中执行此操作。有任何想法吗?
这可能不是最好的方法,所以如果你能推荐一个更好的方法,请赐教: - )

But I can't figure out how to do this in XAML. Any ideas? This is probaly not the best way of doing it, so if you can recommend a better approach, please enlighten me :-)

谢谢!

推荐答案

让我们从模型的角度来看待这个:

Lets examine this from the view towards the model:

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

Lets assume we have 2 different types of views, 1 type of view model:


ViewA - >使用DataTempate / DataTemplateSelector在一个项目控件中创建,Binded>到ViewModelA

ViewA --> Created within an items control using DataTempate/DataTemplateSelector, Binded > to ViewModelA

ViewB - >使用DataTempate / DataTemplateSelector在一个项目控件中创建,Binded到ViewModelA

ViewB --> Created within an items control using DataTempate/DataTemplateSelector, Binded to ViewModelA

如果两个视图绑定到同一视图模型,您最终会得到相同的视图。

If both views are binded to the same view model, you would end up with the same view.

让我们再试两种不同类型的视图和2种不同类型的视图模型:

Lets try again with 2 different types of views and 2 different types of view models:


ViewA - >使用DataTempate / DataTemplateSelector在Item控件中创建,Binded到ViewMod elA - >绑定到ModelA

ViewA --> Created within an items control using DataTempate/DataTemplateSelector, Binded to ViewModelA --> Binded to ModelA

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

ViewB --> Created within an items control using DataTempate/DataTemplateSelector, Binded to ViewModelB --> Binded to ModelB

这是可能的。

现在如果您为这样的视图模型和模型建模(伪代码):

Now if you model your view-models and models like this (pseudo code):

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,
视图将绑定到VM项目,而不是模型项目。

then you will get correct type of VMs for each model item, view will be binded to VM items, not model items.

查看数据表:

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

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

查看物品管理:

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

这篇关于根据对象类型将视图注入ItemsControl的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆