我有三个模型(联系人,备注,提醒)。我想搜索所有这些并在单个列表视图中生成过滤结果,并根据选择我将在其右侧显示相应的视图(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中的某些属性。我尝试使用绑定到ListView的SelectedItem的IsContactViewSelected
属性的setter来设置像IsNoteViewSelected
,SelectedEntity
这样的bool属性。
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
}
}
[[此处陈述的能见度问题已解决]]
答案 0 :(得分: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 Data Foundation的库,它可以更轻松地根据类来切换源属性名称:
<!-- First column -->
<GridViewColumn Header="Title"
DisplayMemberBinding="{edf:ExpressionBinding
context is local:ContactModel ? Name : Title}" />
<!-- Second column -->
<GridViewColumn ... />
我希望很快就会释放我的图书馆以供其他人使用,或者你可以自己编写。与此同时,具有多个DataTemplates的解决方案可以工作,并且比创建ViewModel并在其中镜像您的属性更清晰。