Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Merge ItemsSource Lists

I am working with a 2 lists in a backend class. Each list is a different type. Would like to present the user with a single list (containing a union of both lists) of which when an item in this list is selected the item's details appear.

The code will look something like:

My backend class looks somethings like this

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

My XAML Looks Something Like This

<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>

Any suggestions?

like image 251
Gus Avatar asked Jul 14 '10 17:07

Gus


2 Answers

You can use a CompositeCollection for this. Have a look at this question.

like image 79
Christo Avatar answered Nov 16 '22 01:11

Christo


I don't understand why you don't just have expose a property like this in your ViewModel:

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

and then in your xaml you do this:

<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>

UPDATE:

If you need to manipulate your model differently do the following:

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);
  }
}

This is just an example. But if you modify the above to meet your needs, it might get you to your goal

like image 34
Jose Avatar answered Nov 16 '22 02:11

Jose