##目的
以下の機能を持つUIを作る。ButtonをクリックしたらCheckマークがついたListViewの行の情報を取得しメソッドを実行する。
##前提知識
・WPFの基礎
・オブジェクト指向
・リスト
・自動プロパティ
##方針
1.ListViewの中にGridViewを入れ表を追加
2.ListViewにチェックボックスを追加
3.ListviewのヘッダーにCheckBoxを追加し、チェックした場合全Itemがチェックされる。アンチェックした場合、全Itemを解除する。
4.ListViewの項目を選択しメソッドを実行する
##1.ListViewの中にGridViewを入れ表を追加
###1.UI
###1.XAML
ListViewとListViewにデータを追加するボタンを配置します。
ListViewの中にGridViewを入れることで行と列に値を配置できる表を作成できます。
<Window x:Class="Listview0.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:Listview0"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid Margin="0,67,-0.4,0">
<Button Content="Button" HorizontalAlignment="Left" Margin="21,-41,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
<ListView Margin="0,0,9.6,0">
<ListView.View>
<GridView>
<GridViewColumn Header="項目" Width="200" DisplayMemberBinding="{Binding items}"/>
<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>
###1.メインのソースコード
namespaceの中にMainWindowクラスとデータを格納するListViewItemsクラスを作ります。
Button_Clickの中でデータを格納するリストを作りAddメソッドでデータを入れていきます。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Listview0
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
List<ListViewItems> items = new List<ListViewItems>();
items.Add(new ListViewItems() { items = "000", items1 = "111", items2 = "222", items3 = "333" });
items.Add(new ListViewItems() { items = "aaa", items1 = "bbb", items2 = "ccc", items3 = "ddd" });
items.Add(new ListViewItems() { items = "AAA", items1 = "BBB", items2 = "CCC", items3 = "DDD" });
ListViewName.ItemsSource = items;
}
}
public class ListViewItems
{
public string items { get; set; }
public string items1 { get; set; }
public string items2 { get; set; }
public string items3 { get; set; }
}
}
##2-1
2-1ではXAMLでチェックボックスを定義。
###2-1.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>
<!--GridViewColumnにCheckBoxを追加する-->
<GridViewColumn >
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Margin="5,0" IsChecked="true"/>
</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>
###2-1.XAML解説
ListViewの1列目に表示されるCheckBoxを追加します。
DataTemplateは列のセルの書式を設定するために使用されます。
<GridViewColumn.CellTemplate>
<DataTemplate>
//ここにCheckBoxを入れる
</DataTemplate>
</GridViewColumn.CellTemplate>
CheckBoxでIsCheckedをtrueにすると初期状態でCheckBoxにチェックが入ります。falseではチェックは入りません。
<CheckBox Margin="5,0" IsChecked="true"/>
###2-1.MainWindowのソースコード
namespace Listview_checkbox
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
List<ListViewItems> items = new List<ListViewItems>();
items.Add(new ListViewItems() { /*items = "000",*/ items1 = "111", items2 = "222", items3 = "333" });
items.Add(new ListViewItems() { /*items = "aaa",*/ items1 = "bbb", items2 = "ccc", items3 = "ddd" });
items.Add(new ListViewItems() { /*items = "AAA",*/ items1 = "BBB", items2 = "CCC", items3 = "DDD" });
ListViewName.ItemsSource = items;
}
}
public class ListViewItems
{
//public string items { get; set; }
public string items1 { get; set; }
public string items2 { get; set; }
public string items3 { get; set; }
}
}
今回は1列目にチェックボックスを追加するためitemsをコメントアウトします。他の列には前回と同じデータを入れます。
##2-2
2-1では全てのチェックボックスの初期値をXMALで指定しましたが、2-2ではコードバインディング、MainWindowで指定します。
###2-2XAML
<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>
<!--最初のGridViewColumnにCheckBocを追加する-->
<GridViewColumn >
<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>
解説
<CheckBox Margin="5,0" IsChecked="{Binding Selected}"/>
IsCheckedをバインディングし、Selectedを変数にします。
MainWindowでSelectedを定義します。
###2-2MainWindow
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Listview_checkbox
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
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;
}
}
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; }
}
}
解説
public bool Selected { get; set; }
Selectedにtrueかfalseを与えるboolとします。
ボタンクリックではListViewItems()内において1,3列目をtrueと2列目にはfalseとしました。
##3.ListviewのヘッダーにCheckBoxを追加し、チェックした場合全Itemがチェックされる。アンチェックした場合、全Itemを解除する。
UIにListViewのヘッダーにCheckBoxを追加し全ItemのCheckとUnCheckを行います。
コードが長くなるので2段階に分けて説明します。
1段階目はListViewコレクションの全要素をセレクトする、2段階目でセレクトした全要素のCheckBoxのCheckを変更していきます。
3-1. UI 段階1
まずListViewコレクションの要素をCastつまり青い選択された状態にする。
ListViewのヘッダーにあるCheckBoxをCheckすると全要素がセレクトされる。一方、CheckBoxがCheckされた状態でCheckを外すと全Itemのセレクトが外れるようにします。
###3-1.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>
###3-1. 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; }
}
}
###3-1. 解説
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);を実行。
##3-2. UI 段階2
ListViewヘッダーのCheckBoxをCheckすると全アイテムがCheckされる、UnCheckされる
###3-2. 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>
###3-2.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; }
}
}
3-2. 解説
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します。
##4. ListViewの項目を選択しメソッドを実行する
###4. XMALコード
前回のコードに対してButton_Clickを追加
<Button Content="Button" HorizontalAlignment="Left" Margin="21,-41,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
###4. 全体のロジックコード
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
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)
{
foreach (ListViewItems item in ListViewName.ItemsSource)
{
//item.Selectedがtrueの場合
if (item.Selected)
{
Excute(item.items1);
}
}
}
private void Excute(string items1)
{
Console.WriteLine(items1);
}
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; }
}
}
###4. 解説
ロジックコードで追加した部分です。
private void Button_Click(object sender, RoutedEventArgs e)
{
foreach (ListViewItems item in ListViewName.ItemsSource)
{
//item.Selectedがtrueの場合
if (item.Selected)
{
Excute(item.items1);
}
}
}
private void Excute(string items1)
{
Console.WriteLine(items1);
}
クリックメソッドを実行すると、foreach文が実行されます。
foreachでは「XMALのNameを"ListViewName"としたListView」の生成に使用されるコレクションから各要素を一つずつ取り出します。
各要素はListViewItemsクラスで定義された変数を保持しておりListViewの行に対応しています。
ここではitem1変数を引数としてメソッドExcuteを実行しています。
例えばListViewの項目1をテスト名にして、Checkしたテスト名だけを選択してメソッドを実行するなんてこともできるようになります。
##まとめ
以下の機能を持つWPFについてもまとめました
1.ListViewの中にGridViewを入れ表を追加
2.ListViewにチェックボックスを追加
3.ListviewのヘッダーにCheckBoxを追加し、チェックした場合全Itemがチェックされる。アンチェックした場合、全Itemを解除する。
4.ListViewの項目を選択しメソッドを実行する