(2020/09/17追記)
私が掲載した内容をよりスマートにして頂いた内容が、 コメント にあります。私の後学のために本記事の内容はそのままにしますが、是非コメントにも目を通してみて下さい。@soi さんご指摘、解説ありがとうございます。
(2020/09/18追記)
リストボックスが複数ある場合に、コード量をもっと少なくする方法を思いついたので、[こちら][] に書きました。
[こちら]:https://qiita.com/Michio029/items/fd597470cc62cfa79ed7 "WPFで使いまわしができる「ListBox.SelectedItemsを取得するメソッド」"
(2020/09/26追記)
僕が知る中で一番簡単な ListBox.SelectedItems
を取得する方法を 別記事のコメント に頂きました。
#背景
WPF に用意されている ListBox の SelectedItem は簡単に取り出せるのですが SelectedItem"s" を取り出すのに少し苦労したのでその備忘録です。
SelectedItem(単体選択)の取り出し方は [別記事][] に書きました。
[別記事]:https://qiita.com/Michio029/items/a12a9bac3b7df24397ee "WPFで中身がClassアイテムのListBox.SelectedItemを取得する"
<Window><!-- Windowの細かいのは省略 -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<ListBox Grid.Row="0" Name="ExampleList" Margin="10" SelectionMode="Extended" ScrollViewer.VerticalScrollBarVisibility="Auto">
<!-- SelectionMode="Extended" :ctrl,shift+クリックで複数選択可能 -->
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Id, StringFormat=IDは{0} :}"/>
<TextBlock Text="{Binding Name, StringFormat= Nameは{0} :}"/>
<TextBlock Text="{Binding Age, StringFormat= Ageは{0}}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Grid.Row="1" Name="Btn" Content="ボタン" Margin="100,10,100,10" Click="Btn_Click"/>
</Grid>
</Window>
<TextBlock Text="{Binding Id, StringFormat=IDは{0} :}"/>
この辺の文字列のフォーマットの書き方についてはこちらで詳しく解説してくれています。
https://qiita.com/koara-local/items/815eb5146b3ddc48a8c3
public partial class MainWindow : Window
{
List<ExampleClass> list = new List<ExampleClass>();
public MainWindow()
{
InitializeComponent();
list.Add(new ExampleClass() { Id = 0, Name = "aaa", Age = 10 });
list.Add(new ExampleClass() { Id = 1, Name = "bbb", Age = 20 });
list.Add(new ExampleClass() { Id = 2, Name = "ccc", Age = 30 });
list.Add(new ExampleClass() { Id = 3, Name = "ddd", Age = 40 });
list.Add(new ExampleClass() { Id = 4, Name = "eee", Age = 50 });
ExampleList.ItemsSource = list;
}
private void Btn_Click(object sender, RoutedEventArgs e)
{
}
}
class ExampleClass
{
public int Id { get; set; }
public string Name { get; set; }
public byte Age { get; set; }
}
#選択状態の中身を見てみる
複数選択時の中身がどうなっているのか知りたいので、ボタンを押すところでブレークポイントを設定してみます。
ボタンを押してブレークします。
どうやら SelectedItems 自体は配列になっていて、その中身が SelectedItem と同じっぽいです。
Count は 0 からではなく 1 から始まるみたいですね。3つ選択中なので3。
これを見ると foreach の中で SelectedItem(単体選択) を取り出すときと同じことをしたら取り出せる気がします。
#SelectedItems(複数選択)を取り出す
ボタンに動作を追記します
private void Btn_Click(object sender, RoutedEventArgs e)
{
// 選択項目が0 => メソッドを出る
if (ExampleList.SelectedItems.Count == 0)
return;
// 空の配列を宣言
int[] _id = new int[0];
string[] _name = new string[0];
byte[] _age = new byte[0];
int i = 0;
// SelectedItemsの中身を取り出す
foreach (var oneItemLine in ExampleList.SelectedItems)
{
// 配列の箱を一つ増やす
int reLength = _id.Length + 1;
Array.Resize(ref _id, reLength);
Array.Resize(ref _name, reLength);
Array.Resize(ref _age, reLength);
// ExampleClassとして取り出す
ExampleClass item = oneItemLine as ExampleClass;
_id[i] = item.Id;
_name[i] = item.Name;
_age[i] = item.Age;
i++;
}
// 三つ選択がある(SelectedItems.Count=3)としたら、3回ループして欲しい(n=0,1,2)ので n < SelectedItems.count
for (int n = 0; n < ExampleList.SelectedItems.Count; n++)
{
Console.WriteLine("Id:「{0}」 Name:「{1}」 Age:「{2}」", _id[n], _name[n], _age[n]);
}
}
実行してボタンを押してみます
Id:「0」 Name:「aaa」 Age:「10」
Id:「1」 Name:「bbb」 Age:「20」
Id:「2」 Name:「ccc」 Age:「30」
取れました。
どうやら項目は選択した順に入っていくようです。
Id:「4」 Name:「eee」 Age:「50」
Id:「2」 Name:「ccc」 Age:「30」
Id:「0」 Name:「aaa」 Age:「10」