I have 2 collections 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 this:
<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 scoped to EffectView.Effects
, but I want the default scope to be EffectView
so I can easily assign multiple collections to the 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>
Any way to accomplish this?
The ItemsSource
of a ListView is the collection whose items will appear in the list. So think for a moment about what you're asking the ListView to do:
Pay attention to that second point: every row must display some item from the Events collection and some item from the Descriptions collection.
Which item shall it pick from each? What's the relationship between the items in the two collections?
It appears that what you really need is a collection of objects that contains both an Event and a Description. You can then bind to that collection to display elements of both entities. Roughly, something like this:
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 this assumes the DataContext of the ListView's parent is 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>
That's not really possible. ItemsSource expects to be passed something that, at a minimum, implements IEnumerable. Even if you implemented IEnumerable on your EffectView, you would need to wrap Effect and EffectDescription into a single object to return.
You could bind your ListView to your Effects collection, then use a custom IValueConverter to take the Effect and return a description. But I'm not sure this would fit your situation.
Your best bet would be to include a wrapper object (i.e. EffectWithDescription) that includes both your Effect and your EffectDescription. Then expose a collection of EffectWithDescription objects. You'd need to ensure that this new collection is keep in sync with the other collections though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With