How to link a ListView with multiple collections stored in the same ViewModel in WPF?

I have 2 collections that I want to bind to a separate GridViewColumn in a ListView :

 public class EffectView : INotifyPropertyChanged { ObservableCollection<Effect> effects; public ObservableCollection<Effect> Effects { get { return this.effects; } set { this.effects = value; this.RaisePropertyChanged ( "Effects" ); } } ObservableCollection<EffectDescription> descriptions; public ObservableCollection<EffectDescription> Descriptions { get { return this.descriptions; } set { this.descriptions = value; this.RaisePropertyChanged ( "Descriptions" ); } } } 

I can do it:

 <ListView ItemsSource="{Binding EffectView.Effects}"> <ListView.View> <GridView> <GridViewColumn Width="Auto" DisplayMemberBinding="{Binding Name}" Header="Name" /> <GridViewColumn Width="Auto" DisplayMemberBinding="{Binding Opacity}" Header="Opacity" /> <GridViewColumn Width="Auto" DisplayMemberBinding="{Binding ?}" Header="Description" /> </GridView> </ListView.View> </ListView> 

But then everything is limited by EffectView.Effects , but I want the default area to be EffectView , so I can easily assign multiple collections of ListView .

Something like:

 <ListView ItemsSource="{Binding EffectView}"> <ListView.View> <GridView> <GridViewColumn Width="Auto" DisplayMemberBinding="{Binding Effects Path=Name}" Header="Name" /> <GridViewColumn Width="Auto" DisplayMemberBinding="{Binding Effects Path=Opacity}" Header="Opacity" /> <GridViewColumn Width="Auto" DisplayMemberBinding="{Binding Descriptions Path=Usage}" Header="Description" /> </GridView> </ListView.View> </ListView> 

Can this be done?

+6
c # data-binding wpf xaml
source share
2 answers

ItemsSource ListView is a collection whose items will be displayed in the list. So think about what you are asking for a ListView:

  • As the source set, use something that is not a collection but contains them
  • For each row in the list, displays an item from one collection and an item from another collection

Pay attention to this second point: each line should display some element from the Events collection and some element from the description collection.

Which item to choose from each? What is the relationship between the elements in the two collections?

It looks like you really need a collection of objects containing both the event and the description. Then you can bind this collection to display elements of both objects. Like that:

 public class EffectView : INotifyPropertyChanged { ObservableCollection<EffectsAndDescriptions> effects; public ObservableCollection<EffectAndDescriptions> Effects { get { return this.effects; } set { this.effects = value; this.RaisePropertyChanged ( "EffectsAndDescriptions" ); } } } internal class EffectsAndDescriptions { public Effect Effect { get; set; } public Description Description { get; set; } } 

Now you can bind to the EffectsAndDescriptions collection (note that it is assumed that the DataContext of the ListView EffectView )

 <ListView ItemsSource="{Binding EffectsAndDescriptions}"> <ListView.View> <GridView> <GridViewColumn Width="Auto" DisplayMemberBinding="{Binding Effect.Name}" Header="Name" /> <GridViewColumn Width="Auto" DisplayMemberBinding="{Binding Effect.Opacity}" Header="Opacity" /> <GridViewColumn Width="Auto" DisplayMemberBinding="{Binding Description.Usage}" Header="Description" /> </GridView> </ListView.View> </ListView> 
+8
source share

This is not real. ItemsSource expects something to be passed that, at a minimum, implements IEnumerable. Even if you injected IEnumerable into your EffectView, you still need to wrap Effect and EffectDescription in one return object.

You can associate your ListView with a collection of effects, and then use a custom IValueConverter to accept the effect and return the description. But I'm not sure if this would be appropriate for your situation.

It is best to include a wrapper object (i.e. EffectWithDescription), which includes both your effect and your effect. Then output a collection of EffectWithDescription objects. You will need to ensure that this new collection is in sync with other collections.

+1
source share

All Articles