Как привязать ListView к нескольким коллекциям, хранящимся в одной ViewModel в WPF?
у меня есть 2 коллекции, которые я хочу привязать к отдельной GridViewColumn
на 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" );
}
}
}
Я могу сделать это:
<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>
но тогда все ограничено EffectView.Effects
, но я хочу, чтобы масштаб по умолчанию EffectView
поэтому я могу легко назначить несколько коллекций ListView
.
что-то типа:
<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>
любой способ сделать это?
2 ответов
на ItemsSource
из ListView является коллекция чьи элементы будут отображаться в списке. Поэтому подумайте на мгновение о том, что вы просите ListView сделать:
- в качестве исходной коллекции используйте то, что не является коллекцией, но содержит их
- для каждой строки в списке отобразите элемент из одной коллекции и элемент из другой коллекции
обратите внимание на этот второй момент: каждая строка должна отображать какой-то элемент из коллекции Events и некоторого элемента из коллекции Descriptions.
какой пункт он должен выбрать из каждого? Какова связь между элементами в двух коллекциях?
это появляется то, что вам действительно нужно, это коллекция объектов, которая содержит и событие и описание. Затем можно выполнить привязку к этой коллекции для отображения элементов обеих сущностей. Примерно, что-то вроде это:
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; }
}
теперь вы можете привязаться к коллекции EffectsAndDescriptions (обратите внимание, что это предполагает DataContextродитель 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>
Это действительно невозможно. ItemsSource ожидает, что будет передано что-то, что, как минимум, реализует IEnumerable. Даже если вы реализовали IEnumerable в своем EffectView, вам нужно будет обернуть эффект и EffectDescription в один объект для возврата.
вы можете привязать ListView к коллекции эффектов, а затем использовать пользовательский IValueConverter для получения эффекта и возврата описания. Но я не уверен, что это подходит к вашей ситуации.
ваш лучший выбор было бы включить объект-оболочку (т. е. EffectWithDescription), который включает как ваш эффект, так и Ваше EffectDescription. Затем предоставьте коллекцию объектов EffectWithDescription. Вам нужно будет убедиться, что эта новая коллекция синхронизируется с другими коллекциями.