前回WPFにおいて、「ListViewにCheckBoxを追加するには」について取り上げました。 gaishiengineer.hatenablog.com
今回は上記のUIにListViewのヘッダーにCheckBoxを追加し全ItemのCheckとUnCheckを行います。 コードが長くなるので2段階に分けて説明します。 1段階目はListViewコレクションの全要素をセレクトする、2段階目でセレクトした全要素のCheckBoxのCheckを変更していきます。
UI 段階1
まずListViewコレクションの要素をCastつまり青い選択された状態にする。 ListViewのヘッダーにあるCheckBoxをCheckすると全要素がセレクトされる。一方、CheckBoxがCheckされた状態でCheckを外すと全Itemのセレクトが外れるようにします。
XAML
<Window x:Class="Listview_checkbox.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Listview_checkbox" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid Margin="-1,65,0.6,0"> <Button Content="Button" HorizontalAlignment="Left" Margin="21,-41,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/> <ListView Name="ListViewName"> <ListView.View> <GridView> <!--最初の列にCheckBocを追加する--> <GridViewColumn > <GridViewColumn.Header> <CheckBox Name="CheckBox_PendingListAll" Checked="chkSelectAll_Checked" Unchecked="chkSelectAll_Unchecked" HorizontalAlignment="Center" VerticalAlignment="Center"/> </GridViewColumn.Header> <GridViewColumn.CellTemplate> <DataTemplate> <CheckBox Margin="5,0" IsChecked="{Binding Selected}"/> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="項目1" Width="200" DisplayMemberBinding="{Binding items1}"/> <GridViewColumn Header="項目2" Width="200" DisplayMemberBinding="{Binding items2}"/> <GridViewColumn Header="項目3" Width="200" DisplayMemberBinding="{Binding items3}"/> </GridView> </ListView.View> </ListView> </Grid> </Window>
MainWindow.xaml.cs
using System; using System.Collections.Generic; using System.Windows; namespace Listview_checkbox { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); //ListView List<ListViewItems> items = new List<ListViewItems>(); items.Add(new ListViewItems() { Selected = true, items1 = "111", items2 = "222", items3 = "333" }); items.Add(new ListViewItems() { Selected = false, items1 = "bbb", items2 = "ccc", items3 = "ddd" }); items.Add(new ListViewItems() { Selected = true, items1 = "BBB", items2 = "CCC", items3 = "DDD" }); ListViewName.ItemsSource = items; } private void Button_Click(object sender, RoutedEventArgs e) { } private void chkSelectAll_Checked(object sender, RoutedEventArgs e) { foreach (ListViewItems item in ListViewName.ItemsSource) { ListViewName.SelectedItems.Add(item); } } private void chkSelectAll_Unchecked(object sender, RoutedEventArgs e) { foreach (ListViewItems item in ListViewName.ItemsSource) { ListViewName.SelectedItems.Remove(item); } } } public class ListViewItems { public bool Selected { get; set; } public string items1 { get; set; } public string items2 { get; set; } public string items3 { get; set; } } }
解説
ListViewのヘッダーにCheckBoxを配置し、CheckとUnCheckしたときのメソッドを追加する。
<GridViewColumn.Header> <CheckBox Name="CheckBox_PendingListAll" Checked="chkSelectAll_Checked" Unchecked="chkSelectAll_Unchecked" HorizontalAlignment="Center" VerticalAlignment="Center"/> </GridViewColumn.Header>
chkSelectAll_Checkedが実行されれば foreachを用いListViewName.ItemsSourceにある全要素取り出し、 ListViewName.SelectedItems.Add(item)を実行。 chkSelectAll_Uncheckedが実行されれば foreachを用いListViewName.ItemsSourceにある全要素取り出し、 ListViewName.SelectedItems.Remove(item);を実行。
UI 段階2
ListViewヘッダーのCheckBoxをCheckすると全アイテムがCheckされる、UnCheckされる
XAML
<Window x:Class="Listview_checkbox.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Listview_checkbox" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid Margin="-1,65,0.6,0"> <Button Content="Button" HorizontalAlignment="Left" Margin="21,-41,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/> <ListView Name="ListViewName" SelectionChanged="ListViewName_SelectionChanged"> <ListView.View> <GridView> <!--最初の列にCheckBocを追加する--> <GridViewColumn > <GridViewColumn.Header> <CheckBox Name="CheckBox_PendingListAll" Checked="chkSelectAll_Checked" Unchecked="chkSelectAll_Unchecked" HorizontalAlignment="Center" VerticalAlignment="Center"/> </GridViewColumn.Header> <GridViewColumn.CellTemplate> <DataTemplate> <CheckBox Margin="5,0" IsChecked="{Binding Selected}"/> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="項目1" Width="200" DisplayMemberBinding="{Binding items1}"/> <GridViewColumn Header="項目2" Width="200" DisplayMemberBinding="{Binding items2}"/> <GridViewColumn Header="項目3" Width="200" DisplayMemberBinding="{Binding items3}"/> </GridView> </ListView.View> </ListView> </Grid> </Window>
MainWindow.xaml.cs
using System; using System.Collections.Generic; using System.Windows; namespace Listview_checkbox { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); //ListView List<ListViewItems> items = new List<ListViewItems>(); items.Add(new ListViewItems() { /*items = "000",*/ Selected = true, items1 = "111", items2 = "222", items3 = "333" }); items.Add(new ListViewItems() { /*items = "aaa",*/ Selected = false, items1 = "bbb", items2 = "ccc", items3 = "ddd" }); items.Add(new ListViewItems() { /*items = "AAA",*/ Selected = true, items1 = "BBB", items2 = "CCC", items3 = "DDD" }); ListViewName.ItemsSource = items; } private void Button_Click(object sender, RoutedEventArgs e) { } private void chkSelectAll_Checked(object sender, RoutedEventArgs e) { foreach (ListViewItems item in ListViewName.ItemsSource) { ListViewName.SelectedItems.Add(item); } } private void chkSelectAll_Unchecked(object sender, RoutedEventArgs e) { foreach (ListViewItems item in ListViewName.ItemsSource) { ListViewName.SelectedItems.Remove(item); } } private void ListViewName_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (e.AddedItems.Count > 0) { //------------ ListViewItems user = (ListViewItems)e.AddedItems[0]; ListViewItem lvi = (ListViewItem)ListViewName.ItemContainerGenerator.ContainerFromItem(user); CheckBox chkBx = FindVisualChild<CheckBox>(lvi); if (chkBx != null) chkBx.IsChecked = true; //------------ } else // Remove Select All chkBox { ListViewItems user = (ListViewItems)e.RemovedItems[0]; ListViewItem lvi = (ListViewItem)ListViewName.ItemContainerGenerator.ContainerFromItem(user); CheckBox chkBx = FindVisualChild<CheckBox>(lvi); if (chkBx != null) chkBx.IsChecked = false; } } public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject { if (depObj != null) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) { DependencyObject child = VisualTreeHelper.GetChild(depObj, i); if (child != null && child is T) { return (T)child; } T childItem = FindVisualChild<T>(child); if (childItem != null) return childItem; } } return null; } } public class ListViewItems { //public string items { get; set; } public bool Selected { get; set; } public string items1 { get; set; } public string items2 { get; set; } public string items3 { get; set; } } }
解説
ListViewでSelectとされた要素に変更を与えるメソッド ListViewName_SelectionChangedをXAMLとMainWindowに追加します。 すでに段階1で記載したchkSelectAll_checkedとchkSelectAll_Uncheckedで全アイテムのSelect変更が行われその次に ListViewName_SelectionChangedが実行されます。
<ListView Name="ListViewName" SelectionChanged="IvTestItems_SelectionChanged"> <ListView.View>
ListViewName_SelectionChangedの実装をもってすべてのCheckBoxをCheckまたはUnCheckします。
次回
ListViewのCheckBoxでCheckされた項目を選択しメソッドを実行する