CollectionViewSourceを使ったグルーピングあれこれ【その1】
CollectionViewSourceを使った応用や問題点、およびその解決策について何回かに渡って紹介します。
今回は【その1】として、簡単なグルーピングを行った例を掲載します。これを元にいろいろ発展させていく予定です。
<Window x:Class="WPFGroupingExamples.単純GroupingView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WPFGroupingExamples" Title="単純GroupingView" Height="393" Width="693"> <Window.DataContext> <local:単純GroupingViewModel /> </Window.DataContext> <Window.Resources> <DataTemplate x:Key="グループヘッダTemplate"> <StackPanel Background="#FFCDF2CD"> <TextBlock Text="{Binding Name}" FontWeight="Bold"/> <Rectangle Height="1" Fill="Blue"/> </StackPanel> </DataTemplate> </Window.Resources> <Grid> <ListView ItemsSource="{Binding UICollectionViewSource.View, Mode=OneWay}" Margin="0,0,0,37"> <ListView.GroupStyle> <GroupStyle HeaderTemplate="{StaticResource グループヘッダTemplate}"/> </ListView.GroupStyle> <ListView.View> <GridView> <GridView.Columns> <GridViewColumn Header="大会ID" DisplayMemberBinding="{Binding 大会ID}" Width="Auto" /> <GridViewColumn Header="大会名" DisplayMemberBinding="{Binding 大会名}" Width="Auto" /> <GridViewColumn Header="ランナーID" DisplayMemberBinding="{Binding ランナーID}" Width="Auto" /> <GridViewColumn Header="ランナー名" DisplayMemberBinding="{Binding ランナー名}" Width="Auto" /> <GridViewColumn Header="タイム" DisplayMemberBinding="{Binding タイム}" Width="Auto" /> </GridView.Columns> </GridView> </ListView.View> </ListView> <Button Content="ソート・グループ化適用" Command="{Binding ソート・グループ化適応Command, Mode=OneWay}" Height="23" HorizontalAlignment="Left" Margin="100,329,0,0" Name="button1" VerticalAlignment="Top" Width="157" /> </Grid> </Window>
以下に出てくるRelayCommandについては、以下を参考にして下さい。
Model-View-ViewModel デザイン パターンによる WPF アプリケーション
http://msdn.microsoft.com/ja-jp/magazine/dd419663.aspx
using System; using System.Collections.ObjectModel; using System.Windows.Data; using System.ComponentModel; using System.Windows.Input; using WPFGroupingExamples.Helpers; namespace WPFGroupingExamples { class 単純GroupingViewModel { #region コンストラクタ public 単純GroupingViewModel() { ソート・グループ化適応Command = new RelayCommand(ソート・グループ設定); ObservableCollection<ランナー> uiobjects = new ObservableCollection<ランナー>(); uiobjects.Add(new ランナー { 大会ID = 1, 大会名 = "サロマ100km", ランナーID = 1, ランナー名 = "関西太郎", タイム = new TimeSpan(11, 59, 35) }); uiobjects.Add(new ランナー { 大会ID = 2, 大会名 = "隠岐ウルトラ100km", ランナーID = 1, ランナー名 = "関西太郎", タイム = new TimeSpan(12, 22, 31) }); uiobjects.Add(new ランナー { 大会ID = 3, 大会名 = "四万十川ウルトラ100km", ランナーID = 1, ランナー名 = "関西太郎", タイム = new TimeSpan(12, 01, 28) }); uiobjects.Add(new ランナー { 大会ID = 1, 大会名 = "サロマ100km", ランナーID = 2, ランナー名 = "関東洋子", タイム = new TimeSpan(11, 16, 22) }); uiobjects.Add(new ランナー { 大会ID = 2, 大会名 = "隠岐ウルトラ100km", ランナーID = 2, ランナー名 = "関東洋子", タイム = new TimeSpan(11, 45, 42) }); uiobjects.Add(new ランナー { 大会ID = 3, 大会名 = "四万十川ウルトラ100km", ランナーID = 2, ランナー名 = "関東洋子", タイム = new TimeSpan(11, 14, 17) }); UICollectionViewSource = new CollectionViewSource(); UICollectionViewSource.Source = uiobjects; } #endregion #region プロパティ /// <summary> /// UIに表示するCollectionViewSourceを取得する。 /// </summary> CollectionViewSource _UICollectionViewSource; public CollectionViewSource UICollectionViewSource { get { return _UICollectionViewSource; } set { _UICollectionViewSource = value; } } #endregion #region コマンド /// <summary> /// ソートおよびグループ化を実行するコマンド /// </summary> public ICommand ソート・グループ化適応Command { get; private set; } #endregion #region コマンドハンドラ /// <summary> /// ソートおよびグループ化を実行する。 /// </summary> private void ソート・グループ設定(object obj) { SortDescription sortDescription; PropertyGroupDescription groupDescription; //ソートの指定 UICollectionViewSource.SortDescriptions.Clear(); sortDescription = new SortDescription { PropertyName = "大会ID", Direction = ListSortDirection.Ascending }; UICollectionViewSource.SortDescriptions.Add(sortDescription); sortDescription = new SortDescription { PropertyName = "ランナーID", Direction = ListSortDirection.Ascending }; UICollectionViewSource.SortDescriptions.Add(sortDescription); //グループの指定 UICollectionViewSource.GroupDescriptions.Clear(); groupDescription = new ランナーGroupDescription { PropertyName = "ランナーID" }; UICollectionViewSource.GroupDescriptions.Add(groupDescription); UICollectionViewSource.View.Refresh(); } #endregion #region GroupDescription class ランナーGroupDescription : PropertyGroupDescription { public override object GroupNameFromItem(object item, int level, System.Globalization.CultureInfo culture) { var uiobject = (ランナー)item; return uiobject.ランナー名; } } #endregion } #region ランナー クラス class ランナー { public int 大会ID { get; set; } public string 大会名 { get; set; } public int ランナーID { get; set; } public string ランナー名 { get; set; } public TimeSpan タイム { get; set; } } #endregion }
上記を実行すると以下の画面が表示されます。
「ソート・グループ化適用」ボタンを押すと、次のように表示されます。