我有三个模型(联系人、笔记、提醒)。我想搜索所有这些并在单个 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/