我正在寻找在不同视图之间切换的正确方法。我的场景类似于 Windows 8 上的 Widnows Explorer,您可以在其中切换“超大图标”、“小图标”、“详细信息”等。在 Windows 8 中,用户可以通过资源管理器的“查看”功能区进行操作(您还可以在 XP 和 7 中更改视图)。
就我而言,我有一个朋友列表,我想让用户在“小”、“大”和“细节”视图之间切换。
假设我的视图模型有一个朋友列表:
public class FriendVM {
public name { get; set; }
public smallImage { get; set; }
public largeImage { get; set; }
};
public class MainVM : INotifyPropertyChanged {
public ObservableCollection<FriendVM> friends { get; set; }
private string m_viewMode
public string viewMode {
get { return m_viewMode; }
set { m_viewMode=value; this.PropertyChanged( new PropertyChangedEventArags("viewMode") ); }
}
}
在我看来,我有一个功能区(用户可以在其上更改 viewMode)、一个标题(显示有关用户的详细信息)和一个朋友列表。取决于视图,我想显示:
- 当 viewMode = "details" 我有一个 ListView,带有一个 GridView。
- 当 viewMode = "small" 我有一个 ListView,ItemsPanel 是一个 WrapPanel,我将图像绑定到 smallImage
- 当 viewMode = "large" 我有一个带有 WrapPanel 的 ListView,使用 largeImage 属性。
这是我的 XML 的样子(简化):
<Window x:Class="friends.MainWindow" ... xmlns:f="clr-namespace:friends" ...>
<Window.DataContext>
<f:MainVM />
<Window.DataContext>
<Window.Resources>
<ControlTemplate x:Key="details">
<ListView ItemsSource="{Binding Path=friends}">
<ListView.View>
<GridView>
...
</GridView>
</ListView.View>
</ControlTemplate>
<ControlTemplate x:Key="small">
<ListView ItemsSource="{Binding Path=friends}">
<ListView.ItemsPanel><WrapPanel Orientation="Horizontal" />
</ListView>
<ListView.ItemTemplate><DataTemplate>
<Image Source={Binding smallPicture} Width="32" Height="32" />
</DataTemplate></ListView.ItemTemplate>
</ControlTemplate>
<ControlTemplate x:Key="large">
<ListView ItemsSource="{Binding Path=friends}">
<ListView.ItemsPanel><WrapPanel Orientation="Horizontal" />
</ListView>
<ListView.ItemTemplate><DataTemplate>
<StackPanel>
<Image Source="{Binding largePicture}" Width="200" Height="200" />
<TextBlock Text="{Binding name}" />
</StackPanel>
</DataTemplate></ListView.ItemTemplate>
</ControlTemplate>
</Window.Resource>
<DockPanel LastChildFill="True">
<Ribbon ...>
...
</Ribbon>
<StackPanel>
... some header stuff
</StackPanel>
<ContentControl x:Name="friendList" Content="{Binding friends}" ?????? />
</DockPanel>
</Window>
所以,我的问题是我该怎么办??????区域。现在,我已经Template="{StaticResource small}"
并且它正在工作。此外,使用后面的代码,我可以将模板更改为任何其他资源模板(使用 FindResource)。但是,我对这个解决方案并不满意,因为我觉得它与 MVVM 模式不符。如果它是“项目”(列表框项目、选项卡项目等),那么我可以使用数据模板,然后使用日期模板选择器。但由于这是一个 ContentControl,而且 ControlTemplateSelector 似乎完全脱离了设计,我不知道该怎么办。
或者,如果我可以将朋友列表“按原样”放在树中,那么也许使用数据模板(具有 TargetType=f:FriendList)我可以让它工作,但我不想实例化另一个朋友列表。DataContext 元素中已经实例化了一个实例。