Отображение нескольких моделей в одном ListView - PullRequest
1 голос
/ 17 июня 2010

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

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

Теперь я попробовал его с помощью 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, связанного с SelectedItem объекта ListView.

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 Ответ

1 голос
/ 17 июня 2010

Я твердо верю в 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 Data Foundation, которая значительно упрощает переключение имени свойства источника на основе класса:

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

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

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

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