WPF合并ItemsSource列表

5

我正在与后端类中的两个列表一起工作。每个列表都是不同类型的。希望向用户呈现单个列表(包含两个列表的并集),当选择此列表中的项目时,该项目的详细信息将出现。

代码将类似于:

我的后端类大致如下

public ObservableCollection<Person> People {get;}
public ObservableCollection<Product> Products {get;}

我的XAML大致长这个样子

<ListBox x:Name="TheListBox" ItemsSource={Some Expression to merge People and Products}>
   <ListBox.Resources>
         People and Product Data Templates
   </ListBox.Resources>
</ListBox>
      ...
<ContentControl Content={Binding ElementName=TheListBox, Path=SelectedItem }>
   <ContentControl.Resources>
         Data Templates for showing People and Product details
   </ContentControl.Resources>
</ContentControl>

有什么建议吗?

我正在寻找类似的东西,可以直接从标记中使用,而不会污染我的视图模型接口。它应该基本上解决由视图模型提供的项目之间的不匹配,这些项目可能是多个集合或仅是几个独立属性,以及WPF所期望的单个可枚举对象之间的不匹配。理想情况下,我甚至希望在标记中直接添加项目,这些项目甚至与视图模型中的任何内容都不对应,但合并到同一个列表中。 - Christo
3个回答

10

这是一个示例:https://msdn.microsoft.com/zh-cn/library/ms742405(v=vs.110).aspx - parfilko

2
我不明白为什么您不直接在ViewModel中公开此属性,像这样:

ObservableCollection<object> Items 
{
  get 
  {
    var list = new ObservableCollection<object>(People);
    list.Add(Product);
    return list;
  }
}

然后在你的XAML中这样做:

<ListBox x:Name="TheListBox" ItemsSource={Binding Items}>
   <ListBox.Resources>
         People and Product Data Templates
   </ListBox.Resources>
</ListBox>
      ...
<ContentControl Content={Binding ElementName=TheListBox, Path=SelectedItem }>
   <ContentControl.Resources>
         Data Templates for showing People and Product details
   </ContentControl.Resources>
</ContentControl>

更新:

如果您需要以不同的方式操作您的模型,请按照以下步骤进行:

ObservableCollection<object> _Items 
ObservableCollection<object> Items 
{
  get 
  {
    if (_Items == null)
    {
      _Items = new ObservableCollection<object>();
      _Items.CollectionChanged += EventHandler(Changed);
    }
    return _Items;
  }
  set 
  { 
    _Items = value;
    _Items.CollectionChanged += new CollectionChangedEventHandler(Changed);
  }
}

void Changed(object sender,CollectionChangedEventArgs e)
{
  foreach(var item in e.NewValues)
  {
    if (item is Person)
      Persons.Add((Person)item);
    else if (item is Product)
      Products.Add((Product)item);
  }
}

这只是一个例子。但是,如果您根据自己的需求进行修改,它可能会帮助您达到目标。


我考虑以类似于你提出的方式来实现它。使我的情景复杂的是,我需要通过用户界面添加和删除列表中的项目的方法。 - Gus

0

我找到了一篇博客文章在这里,它帮助我完成了大部分工作。我使用了作者的AggregateCollection以及一个多值转换器来完成任务。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接