WPF Listview. Как лучше всего отображать данные из разных ObservableCollections на основе нажатия кнопки?

У меня есть три ObservableCollection: CharacterCollection, LocationCollection и ItemCollection. Все они представляют собой наборы объектов; CharacterCollection — это коллекция объектов символов. Мне нужно отобразить в списке информацию из коллекции, определяемой пользователем, нажимающим кнопку. Я бы предпочел использовать привязку данных, но я не вижу четкого способа сделать это с несколькими коллекциями, содержащими разные типы объектов. Как лучше всего легко переключаться между коллекциями?

--Редактировать--

Одна из основных проблем, с которыми я сталкиваюсь, заключается в том, что для разных коллекций требуется разное количество строк и разные заголовки строк.


person Justin    schedule 24.03.2010    source источник


Ответы (3)


Решение, которое может быть даже проще, чем у Рида Копси: вместо того, чтобы возиться с привязками ListView, создайте три разных ListView, и пусть кнопки определяют, какая из них видна. Сделал бы я это так или как Рид, зависит в первую очередь от вещей, о которых вы нам еще не рассказали.

Изменить:

Чтобы ответить на ваш вопрос, мы собираемся выйти за пределы «еще более простой» территории и перейти к теме «почему WPF чертовски крут».

Фактически, более WPFish, MVVMish способ сделать что-то - создать подкласс для каждого из ваших трех типов коллекций - например. тип с именем CharactersCollection, который является подклассом ObservableCollection<Character>. Затем добавьте DataTemplate для каждого из этих типов в словарь ресурсов:

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

Теперь каждый раз, когда в WPF требуется визуализировать CharactersCollection, он находит этот шаблон и использует его.

В классе модели представления вы можете создать такое свойство:

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

Достаточно просто, не так ли? Какая коллекция активна? Как только вы это сделаете, все, что должно представлять свойство ActiveCollection, например:

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

отобразит активную коллекцию, используя DataTemplate, соответствующий типу активной коллекции.

А так как вы реализовали INotifyPropertyChanged, каждый раз, когда вы устанавливаете ActiveCollection, его текущее значение будет отображаться с использованием соответствующего шаблона. Итак, теперь все, что нужно сделать вашим кнопкам, — это установить свойство объекта, который является источником привязок. (Или быть привязанным к Command объектам, которые делают это, но давайте пройдемся, прежде чем бежать.)

person Robert Rossney    schedule 24.03.2010
comment
Я отредактировал свой вопрос с некоторой информацией, которую я должен был включить изначально. Считаете ли вы, что несколько ListViews будут лучшим способом справиться с необходимостью разного количества столбцов и разных заголовков? Будет ли наличие нескольких ListView считаться неаккуратным? - person Justin; 24.03.2010

Просто имейте одно свойство IList в вашей ViewModel (или в коде), например:

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

Как только вы это сделаете, когда вы захотите переключить коллекцию для просмотра, просто установите CurrentCollection = ItemCollection;. Шаблоны данных, используемые ListView, могут без проблем обрабатывать различные типы объектов.

person Reed Copsey    schedule 24.03.2010

WPF CompositeCollection будет обрабатывать коллекции, содержащие объекты любого типа, а также доступен для наблюдения.

Другой вариант с более строгой типизацией — наследование от общего базового класса для всех коллекций, к которым вы хотите привязаться. Затем вы можете создать общее свойство ObservableCollection для привязки в форме ObservableCollection.

person Bermo    schedule 24.03.2010