Как связать ListView с несколькими коллекциями, хранящимися в одной ViewModel в WPF? - PullRequest
6 голосов
/ 24 марта 2011

У меня есть 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 ]

8 голосов
/ 24 марта 2011

ItemsSource ListView - это коллекция , элементы которой появятся в списке.Поэтому задумайтесь на минуту о том, что вы просите сделать ListView:

  • В качестве исходной коллекции используйте что-то, что не является коллекцией, но содержит их
  • Для каждогострока в списке, отображать элемент из одной коллекции и элемент из другой коллекции

Обратите внимание на этот второй пункт: каждая строка должна отображать некоторый элемент из коллекции событий и некоторый элемент изКоллекция описаний.

Какой предмет выбрать из каждого?Какая связь между предметами в двух коллекциях?

кажется , что вам действительно нужно это коллекция объектов, которая содержит и Событие иописание.Затем вы можете привязать эту коллекцию для отображения элементов обеих сущностей.Грубо говоря, что-то вроде этого:

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

Теперь вы можете привязаться к коллекции EffectsAndDescription (обратите внимание, что предполагается, что DataContext родительского элемента 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>
1 голос
/ 24 марта 2011

Это не совсем возможно.ItemsSource ожидает передачи чего-то, что, как минимум, реализует IEnumerable.Даже если вы реализовали IEnumerable в EffectView, вам нужно будет обернуть Effect и EffectDescription в один объект для возврата.

Вы можете привязать свой ListView к своей коллекции Effects, а затем использовать собственный IValueConverter, чтобы получить Effectвернуть описание.Но я не уверен, что это подойдет для вашей ситуации.

Лучше всего было бы включить объект-оболочку (т.е. EffectWithDescription), который включает в себя как ваш Effect, так и ваше EffectDescription.Затем предоставьте коллекцию объектов EffectWithDescription.Вы должны убедиться, что эта новая коллекция синхронизируется с другими коллекциями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...