異なるビューを切り替える正しい方法を探しています。私のシナリオは、Windows 8 の Widnows エクスプローラーに似ており、「特大アイコン」、「小さいアイコン」、「詳細」などを切り替えることができます。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" の場合、GridView を持つ ListView があります。
- viewMode = "small" の場合、ListView があり、ItemsPanel は WrapPanel で、画像を smallImage にバインドします
- viewMode = "large" の場合、largeImage プロパティを使用して、WrapPanel で ListView を作成しました。
これが私の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 要素内でインスタンス化されたインスタンスが既に 1 つあります。