2010-06-17 2 views
1

У меня есть три модели (Контакты, заметки, напоминания). Я хочу искать все эти данные и производить отфильтрованный результат в одном списке, и в зависимости от выбора я должен отображать соответствующее представление (UserControl) справа.Отображение нескольких моделей в одном списке ListView

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

Теперь я пробовал это с помощью IntegratedViewModel, имеющего все свойства от всех трех моделей.

public class IntegratedViewModel 
{ 
    ContactModel _contactModel; 
    NoteModel _noteModel; 

    public IntegratedViewModel(ContactModel contactModel) 
    { 
     _contactModel = contactModel; 
    } // similarly for other models also 

    public string DisplayTitle // For displaying in ListView 
    {    
     get 
     { 
      If(_contactModel != null) 
       return _contactModel.Name; 
      If(_noteModel != null) 
       return _noteModel.Title; 
     } 
    } 

    // All other properties from the three models includin the Name/Title properties for displaying them in the corresponding views(UserControl) 
} 

Теперь я установил itemsSource как List<IntegratedViewModel>.

Я должен привязать видимость представлений к некоторым свойствам в MainViewModel. Я попытался установить свойства bool, такие как IsContactViewSelected, IsNoteViewSelected, используя установщик SelectedEntity, который привязан к элементу ListView SelectedItem.

public SelectedEntity 
{ 
    //get 
    set 
    { 
    oldvalue = _selectedEntity; 
    _selectedEntity = value; 
    // now i find the Type of model selected using `oldvalue.ModelType` 
    // where ModelType is a property in the IntegratedViewModel 
    // according to the type, i set one of the above bool properties to false 
    // and do the same for _selectedEntity but set the property to true 
    // so that the view corresponding to the selectedEntityType is visible 
    // and others are collapsed 
    } 
} 

[[Проблема видимости заявил здесь был решен]]

ответ

1

Я твердо верю в MVVM, но я не верю в создание представлений модели кроме случаев, когда это необходимо. Пока объекты модели должным образом поддерживают уведомление об изменении, и ваше представление не имеет состояния представления, вы можете напрямую использовать объекты модели.

В этом случае здесь. Ваш ListView может напрямую связываться с моделями без каких-либо беспорядков, так что я бы пошел.

Вот что я написал бы еще несколько лет назад, чтобы решить эту проблему:

<ListView ItemsSource="{Binding AllSelections}"> 
    <ListView.View> 
    <GridView> 

     <!-- First column --> 
     <GridViewColumn Header="Title" DisplayMemberBinding="{Binding}"> 
     <GridViewColumn.CellTemplate> 
      <DataTemplate> 
      <DataTemplate.Resources> 

       <!-- First column content for ContactModel objects -->     
       <DataTemplate DataType="{x:Type local:ContactModel}"> 
       <TextBlock Text="{Binding Name}" /> 
       </DataTemplate> 

       <!-- First column content for NoteModel objects -->     
       <DataTemplate DataType="{x:Type local:NoteModel}"> 
       <TextBlock Text="{Binding Title}" /> 
       </DataTemplate> 

       ... 

      </DataTemplate.Resources> 

      <!-- This selects one of the above templates and applies it --> 
      <ContentPresenter /> 

      </DataTemplate> 
     </GridViewColumn.CellTemplate> 
     </GridViewColumn> 

     <!-- Second column --> 
     <GridViewColumn ...> 
     ... 
     </GridViewColumn> 

    </GridView> 
    </ListView.View> 
</ListView> 

Где «AllSelections» свойство в вашем ViewModel, который содержит ICollection, который включает в себя смесь ContactModel, NoteModel и ReminderModel объектов, а также реализует INotifyCollectionChanged.

Этот способ реализации представления довольно ясен и позволяет легко настроить презентацию различных типов объектов.


Сегодня я использую библиотеку, я написал под названием Emerald Foundation Data, что делает его гораздо легче иметь дело с переключением имени исходного свойства на основе класса:

<!-- First column --> 
<GridViewColumn Header="Title" 
       DisplayMemberBinding="{edf:ExpressionBinding 
        context is local:ContactModel ? Name : Title}" /> 

<!-- Second column --> 
<GridViewColumn ... /> 

Я надеюсь выпустить мою библиотеку когда-нибудь скоро для других использовать, или вы могли бы написать свои собственные. Тем временем решение с несколькими DataTemplates работает и намного чище, чем создание ViewModel и зеркальное отражение ваших свойств в нем.

+0

Прежде всего, я хотел бы поблагодарить вас за решение, особенно две вещи: 1) переключение DataTemplate в соответствии с DataType 2) Внедрение общего интерфейса. Поскольку AllSelection должен быть смесью моделей, я создал интерфейс для тезки, имея только свойство ID. AllSelection теперь хорошо связан с списком. Несмотря на то, что я знаю об обоих, нам нужен кто-то, чтобы колоть нас, чтобы использовать его в правильной ситуации. Так здорово, и вы тоже. – Amsakanna