c# - 在单个 ListView 中显示多个模型

标签 c# wpf linq-to-sql mvvm

我有三个模型(联系人、笔记、提醒)。我想搜索所有这些并在单个 ListView 中生成过滤结果,并根据选择在其右侧显示相应的 View (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> .

我现在必须将 View 的可见性绑定(bind)到 MainViewModel 中的某些属性。我尝试设置 bool 属性,如 IsContactViewSelected , IsNoteViewSelected使用 SelectedEntity 的 setter 绑定(bind)到 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
  }
}

[[此处所述的可见性问题已解决]]

最佳答案

我坚信 MVVM,但除非必要,否则我不相信创建 View 模型。只要您的模型对象正确支持更改通知并且您的 View 没有 View 状态,您就可以直接使用模型对象。

这里就是这种情况。您的 ListView 可以直接绑定(bind)到模型而不会造成困惑,这就是我要走的路。

这是我几年前为了解决这个问题而写的:

<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。

这种实现 View 的方式非常清晰,并且可以轻松自定义各种对象类型的表示。

今天我使用了一个我编写的名为 Emerald Data Foundation 的库,它可以更轻松地处理基于类切换源属性名称:
<!-- First column -->
<GridViewColumn Header="Title"
                DisplayMemberBinding="{edf:ExpressionBinding
                  context is local:ContactModel ? Name : Title}" />

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

我希望尽快发布我的库供其他人使用,或者您可以编写自己的库。同时,具有多个 DataTemplates 的解决方案可以工作,并且比创建 ViewModel 并在其中镜像您的属性要干净得多。

关于c# - 在单个 ListView 中显示多个模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3060342/

相关文章:

winforms - Winforms 中使用 linq-to-sql 进行 CRUD

c# - Redis中的处理列表

c# - 检查 WPF DataGrid 中的可见行

c# - 如何从视频中抓取一帧?

c# - 将多个图像文件发送到 mySQL

c# - WPF Datagrid在添加新项目后进入编辑

.net - 谁能给我一个关于 InsertOnSubmit 和 InsertAllOnSubmit 的解释性例子

LINQ 错误 Group by sum 上的列名无效

c# - 查找将窗口停靠到左侧/右侧

c# - 我可以在呈现控件时将英语数字更改为阿拉伯语/波斯语表示形式吗?