views:

56

answers:

3

I have three ObservableCollections: CharacterCollection, LocationCollection, and ItemCollection. They are all collections of objects; CharacterCollection is a collection of Character Objects. I need to display, in the listview, information from the collection determined by the user clicking on a button. I would prefer to use databinding, but I don't see a clear cut way to do that with multiple collections containing different types of objects. What would be the best way to easily switch between collections?

--Edit--

One of the major problems that I am having is that the different Collections each require a different number of rows and different row headers.

+2  A: 

Just have a single IList property on your ViewModel (or code behind), like:

private IList currentCollection;
public IList CurrentCollection
{
   get { return this.currentCollection; }
   set
   {
       if (this.currentCollection != value)
       {
           this.currentCollection = value;
           var handler = this.PropertyChanged;
           if (handler != null)
               handler(this, new PropertyChangedEventArgs("CurrentCollection");
       }
   }

Once you've done that, when you want to switch which collection to view, just set CurrentCollection = ItemCollection;. The DataTemplates used by the ListView can handle the different types of objects without issue.

Reed Copsey
A: 

The WPF CompositeCollection will handle collections containing objects of any type and is also observable.

Another option that is more strongly typed is to inherit from a common base clase for all of the collections you want to bind to. Then you can create a generic ObservableCollection propery to bind to in the form of ObservableCollection.

Bermo
+1  A: 

A solution that may be even simpler than Reed Copsey's: Instead of messing around with the bindings of the ListViews, create three different ListViews, and have the buttons determine which one's visible. Whether I would do it this way or Reed's way depends primarily on things you haven't told us about yet.

Edit:

To answer your question, we're going to get out of "even more simple" territory, and into the territory of "why WPF is freaking awesome."

In fact, the more WPFish, MVVMish way to do things is to create a subclass for each of your three collection types - e.g. a type called CharactersCollection that's a subclass of ObservableCollection<Character>. Then add a DataTemplate for each of these types to the resource dictionary:

<DataTemplate DataType="CharactersCollection">
  <ListView ItemsSource="{Binding}">
     <!-- specific column definitions for character information goes here -->
  </ListView>
</DataTemplate>

Now, any time anything in WPF needs to render a CharactersCollection, it'll find that template and use it.

In your view model class, you can create a property like this:

private object _ActiveCollection;
public object ActiveCollection
{
   get { return _ActiveCollection; } 
   set
   {
      _ActiveCollection = value;
      OnPropertyChanged("ActiveCollection");
   }
}

Simple enough, right? Which collection is active? Once you've done this, anything that needs to present the ActiveCollection property, like this:

<ContentControl Content="{Binding ActiveCollection}"/>

will render the active collection using the DataTemplate that's appropriate for the type of active collection.

And since you've implemented INotifyPropertyChanged, any time you set ActiveCollection, its current value will be rendered with the appropriate template. So now all your buttons need to do is set a property on the object that's the source of the bindings. (Or be bound to Command objects that do that, but let's walk before we run.)

Robert Rossney
I edited my question with some info I should have included originally. Do you think multiple ListViews would be the best way to handle the need for different numbers of columns and different headers? Would having multiple ListViews be considered sloppy?
Justin
Sloppy? Quite the contrary! See my edit.
Robert Rossney
Thank you very much!
Justin