動作環境
Windows 7 Pro (32bit)
Microsoft Visual Studio 2017 Community
http://gushwell.ldblog.jp/archives/52333865.html
を元に学習中。
リンク先ではListBoxアイテムの選択処理をしている。
選択したアイテムを解除する処理を実装してみた。
- Button追加: B_clear
- B_clearClick()処理実装
MainWindow.xaml.cs
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;
//
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace _170608_t1523_listBoxMultiSelect
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var myList = (this.DataContext as MyDataList);
myList.UpdateSelectedItems();
}
private void B_clearClick(object sender, RoutedEventArgs e)
{
var myList = (this.DataContext as MyDataList);
// 1. 以下ではListBoxの選択状態が残ったままになった
//foreach (var elem in myList)
//{
// elem.bfSelected = false;
//}
//myList.UpdateSelectedItems();
// 2. 以下ではListBoxの選択状態がクリアされる
listBox1.SelectedItems.Clear();
myList.UpdateSelectedItems();
}
}
public class MyData
{
public string Name { get; set; }
public Nullable<bool> bfSelected { get; set; }
}
public class MyDataList : ObservableCollection<MyData>
{
private int lastYear = 2016;
public MyDataList()
{
AddNewItem();
AddNewItem();
AddNewItem();
AddNewItem();
}
public void AddNewItem()
{
var data = new MyData { Name = string.Format("{0}年", lastYear) };
this.Add(data);
lastYear++;
}
public List<MyData> SelectedItems { get; private set; }
public void UpdateSelectedItems()
{
var lnq = Items.Where(
x => x.bfSelected.HasValue &&
(x.bfSelected.Value == true));
SelectedItems = new List<MyData>(lnq);
this.OnPropertyChanged(new PropertyChangedEventArgs("SelectedItems"));
}
}
}
MainWindow.xaml
<Window x:Class="_170608_t1523_listBoxMultiSelect.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:_170608_t1523_listBoxMultiSelect"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MyDataList/>
</Window.DataContext>
<Window.Resources>
<Style x:Key="listBoxItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding bfSelected}"/>
</Style>
</Window.Resources>
<StackPanel>
<Button x:Name="B_clear"
Height="28" Width="100" HorizontalAlignment="Left"
Content="ClearSelection"
Click="B_clearClick"
/>
<Grid VerticalAlignment="Stretch" Height="280">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListBox Name="listBox1"
SelectionMode="Multiple"
ItemsSource="{Binding}"
DisplayMemberPath="Name"
ItemContainerStyle="{StaticResource listBoxItemStyle}"
SelectionChanged="listBox1_SelectionChanged"/>
<ListBox Name="listBox2"
Grid.Column="1"
ItemsSource="{Binding SelectedItems}"
DisplayMemberPath="Name"/>
</Grid>
</StackPanel>
</Window>
code snippet
private void B_clearClick(object sender, RoutedEventArgs e)
{
var myList = (this.DataContext as MyDataList);
// 1. 以下ではListBoxの選択状態が残ったままになった
//foreach (var elem in myList)
//{
// elem.bfSelected = false;
//}
//myList.UpdateSelectedItems();
// 2. 以下ではListBoxの選択状態がクリアされる
listBox1.SelectedItems.Clear();
myList.UpdateSelectedItems();
}
上記において1の処理ではDataContextのmyList要素のbfSelectedはfalseになり、右側のListBoxの表示はクリアされた。
一方で、左側のlistBox1のSelectedItemsは残ったままだった。
(次回選択時に残っていたSelectedItemsも選択状態になった。)
2の処理ではlistBox1のSelectedItemsもクリアされた。
listBox1を直接指定している点はいいのかどうか。Bindingだけで処理できる方が良いようには思う。