WPF ではListBox(リストボックス)と呼ばれる、データを一覧で表示して項目を選択できるGUIコントロールがあります。
ListBox の使い方や書き方を知りたい方は、この記事がオススメです。ぜひ最後まで読んでみて下さい。
オススメの参考書
C#の使い方が丁寧に解説しており、「基礎からしっかりと学びたい」という初心者の方にオススメの一冊です。サンプルコードも記載してあり、各章の最後に復習問題があるので理解度を確認しながら読み進めることができます。新しい C# のバージョンにも対応している書籍です。
ListBoxとは
ListBox とはリスト形式に表示をし、表示された一覧から行を選択できるコントロールです。
<ListBox … />
ListBox は単に文字列のコレクションを一覧で表示するだけではなく、ItemsControl クラスを使って、任意の型(文字列や画像、パネル等)を含むオブジェクトのコレクションを一覧で表示する事ができます。
類似するコントロールとして ComboBox があります。ComboBox は項目を1つしか選択できませんが、ListBox は1行または複数行の選択が可能です。
- ListBox はリスト形式で表示するコントロールである
- ItemsControlでオブジェクトのコレクションを表示できる
- 1行または複数行を選択できる
ListBox をカスタムする事で、様々な表現方法でデータを表示する事ができます。
他の UI コントロールの使い方も知りたい方はこの記事をチェック!!
ListBoxの使い方と書き方
ListBox には、SelectionMode というプロパティがあります。このプロパティは、リストボックスの選択を1行だけにするのか、複数行の選択を可能にするかを設定する事ができます。
次の3つの選択方式で設定ができます。このプロパティは使用する用途に応じて、使い分けをしましょう。
- Single
1つの項目のみ選択が可能である。 - Extended
キーボードの[Controlキー]や[Shiftキー]を押している最中にクリックをすると、複数選択が可能になる。 - Multiple
キーボードのキーを押さなくても、複数選択が可能である。クリックした行が選択状態になり、もう一度クリックする事で選択が解除される。
ListBox の使い方と書き方について、いくつかのパターンを用意しています。
それでは確認してみましょう。
XAMLでデータを表示する方法
XAML を使ってリスト形式にデータを表示する方法です。ListBox に表示したいデータをXAML に記述するので、リストの項目が変わらない場合に使用します。
ListBoxItem クラスの Content プロパティに表示したいデータを設定します。
<Window
x:Class="ListBoxSample.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:local="clr-namespace:ListBoxSample"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="400"
Height="250"
mc:Ignorable="d">
<Grid>
<ListBox Name="ListBox1" Margin="10">
<ListBoxItem Content="Apple" />
<ListBoxItem Content="Banana" />
<ListBoxItem Content="Cherry" />
<ListBoxItem Content="Kiwi" />
<ListBoxItem Content="Orange" />
</ListBox>
</Grid>
</Window>
上記のコードを実行すると次のような結果になります。
ItemsSourceでデータを表示する方法
ソースファイルに ListBox に表示したいデータのコレクションを用意して、ItemsSource プロパティにコレクションを設定します。
データのコレクションを定義する時は List クラスではなく、ObservableCollection クラスを使います。ObservableCollection クラスを使う事で、ItemsSource プロパティに設定したコレクションに要素を追加または削除すると、コレクションの変更が通知されて ListBox の一覧も更新されます。
using System.Windows;
using System.Collections.ObjectModel;
namespace ListBoxSample
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var Items = new ObservableCollection()
{
"Apple",
"Banana",
"Cherry",
"Kiwi",
"Orange",
};
ListBox1.ItemsSource = Items;
}
}
}
XAML は以下になります。
<Window
x:Class="ListBoxSample.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:local="clr-namespace:ListBoxSample"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="400"
Height="250"
mc:Ignorable="d">
<Grid>
<ListBox Name="ListBox1" Margin="10" />
</Grid>
</Window>
上記のコードを実行すると次のような結果になります。
2列以上のデータを横並びで表示する方法
ソースファイルに ListBox に表示したいオブジェクトのコレクションを用意して、ItemsSource プロパティにコレクションを設定します。
ここでは番号・名前・カラーの3つのプロパティを持つクラスを ListBox に表示します。
public class Fruit
{
public int No { get; set; }
public string Name { get; set; }
public string Color { get; set; }
}
XAML では、ListBox の ItemTemplate に Fruit クラスのプロパティをそれぞれの TextBlock に Binding して設定します。
<Window
x:Class="ListBoxSample.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:local="clr-namespace:ListBoxSample"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="400"
Height="250"
mc:Ignorable="d">
<Grid>
<ListBox Name="ListBox1" Margin="10" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding No}" Margin="5,0,5,0"/>
<TextBlock Text="{Binding Name}" Margin="5,0,5,0"/>
<TextBlock Text="{Binding Color}" Margin="5,0,5,0"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
データを格納するコレクションを作成して Add メソッドでオブジェクトを追加します。データの追加が終わったら、ListBox の ItemsSource プロパティにリストを代入します。
using System.Windows;
using System.Collections.ObjectModel;
namespace ListBoxSample
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var Items = new ObservableCollection();
Items.Add(new Fruit { No = 1, Name = "Apple", Color = "Red" });
Items.Add(new Fruit { No = 2, Name = "Banana", Color = "Yellow" });
Items.Add(new Fruit { No = 3, Name = "Cherry", Color = "Red" });
Items.Add(new Fruit { No = 4, Name = "Kiwi", Color = "Green" });
Items.Add(new Fruit { No = 5, Name = "Orange", Color = "Orange" });
ListBox1.ItemsSource = Items;
}
}
}
上記のコードを実行すると次のような結果になります。
選択した項目をテキストコントロールに表示する
ListBox で選択した項目は SelectedItem にデータが格納されます。選択した項目をテキストボックスやテキストブロック等に表示する場合は、SelectedItem からデータを取り出して、コントロールの Text プロパティに Binding します。
「2列以上のデータを表示する方法」で紹介した XAML コードを次のように変更します。
<Window
x:Class="ListBoxSample.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:local="clr-namespace:ListBoxSample"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="400"
Height="250"
mc:Ignorable="d">
<Grid>
<DockPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<TextBlock
Height="30"
Margin="10,0,10,0"
Text="{Binding ElementName=ListBox1, Path=SelectedItem.No}" />
<TextBlock
Height="30"
Margin="10,0,10,0"
Text="{Binding ElementName=ListBox1, Path=SelectedItem.Name}" />
<TextBlock
Height="30"
Margin="10,0,10,0"
Text="{Binding ElementName=ListBox1, Path=SelectedItem.Color}" />
</StackPanel>
<ListBox Name="ListBox1" Margin="10,0,10,10">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="5,0,5,0" Text="{Binding No}" />
<TextBlock Margin="5,0,5,0" Text="{Binding Name}" />
<TextBlock Margin="5,0,5,0" Text="{Binding Color}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
</Grid>
</Window>
上記のコードを実行すると次のような結果になります。
リストに項目を追加・削除する
ListBox はコレクションを表示するだけではなく、「項目の追加」や「項目の削除」を行う事ができます。
コレクションの定義で ObservableCollection クラスを使う事で、ItemsSource プロパティに設定したコレクションに要素を追加または削除すると、コレクションの変更が通知されて ListBox の一覧も更新されます。
UI画面に[項目の追加]ボタンと[項目の削除]ボタンを配置して、そのボタンが押下されたら処理を実行するようにします。
<Window
x:Class="ListBoxSample.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:local="clr-namespace:ListBoxSample"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="400"
Height="250"
mc:Ignorable="d">
<Grid>
<DockPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<Button
Name="btnAdd"
Width="100"
Margin="10,0,0,0"
Click="btnAdd_Click"
Content="項目追加" />
<Button
Name="btnRemove"
Width="100"
Margin="10,0,0,0"
Click="btnRemove_Click"
Content="項目削除" />
</StackPanel>
<ListBox Name="ListBox1" Margin="10">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="5,0,5,0" Text="{Binding No}" />
<TextBlock Margin="5,0,5,0" Text="{Binding Name}" />
<TextBlock Margin="5,0,5,0" Text="{Binding Color}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
</Gri
コレクションへデータを追加するには、Add メソッドで追加したい項目を追加します。コレクション内のデータを削除するには、RemoveAt メソッドで選択された項目を削除します。
using System.Windows;
using System.Collections.ObjectModel;
namespace ListBoxSample
{
public partial class MainWindow : Window
{
ObservableCollection Items = new ObservableCollection();
public MainWindow()
{
InitializeComponent();
Items.Add(new Fruit { No = 1, Name = "Apple", Color = "Red" });
Items.Add(new Fruit { No = 2, Name = "Banana", Color = "Yellow" });
Items.Add(new Fruit { No = 3, Name = "Cherry", Color = "Red" });
Items.Add(new Fruit { No = 4, Name = "Kiwi", Color = "Green" });
Items.Add(new Fruit { No = 5, Name = "Orange", Color = "Orange" });
ListBox1.ItemsSource = Items;
}
private void btnAdd_Click(object sender, RoutedEventArgs e)
{
Items.Add(new Fruit { No = 6, Name = "Strawberry", Color = "Red" });
}
private void btnRemove_Click(object sender, RoutedEventArgs e)
{
//選択項目がない場合は処理せず戻し
if (ListBox1.SelectedItems.Count == 0) return;
Items.RemoveAt(ListBox1.SelectedIndex);
}
}
}
上記のコードを実行すると次のような結果になります。
選択した項目を上下に移動する
ListBox で選択した項目を上下に移動する事ができます。
まずは UI 画面に[上へ移動]ボタンと[下へ移動]ボタンを配置して、そのボタンが押下されたら処理を実行するようにします。
<Window
x:Class="ListBoxSample.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:local="clr-namespace:ListBoxSample"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="400"
Height="250"
mc:Ignorable="d">
<Grid>
<DockPanel>
<StackPanel DockPanel.Dock="Right" Orientation="Vertical">
<Button
Name="btnUp"
Width="60"
Margin="10"
Height="85"
Click="btnUp_Click"
Content="上へ移動" />
<Button
Name="btnDown"
Width="60"
Height="85"
Margin="10"
Click="btnDown_Click"
Content="下へ移動" />
</StackPanel>
<ListBox Name="ListBox1" Margin="10">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="5,0,5,0" Text="{Binding No}" />
<TextBlock Margin="5,0,5,0" Text="{Binding Name}" />
<TextBlock Margin="5,0,5,0" Text="{Binding Color}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
</Grid>
</Window>
ListBox の ItemsSource に設定したコレクションを操作する事で、項目の順番を入れ替えます。操作の手順としては次のようになります。
- 選択されている項目とインデックス番号を取得する
- 選択されている項目を削除する
- 削除した項目の1つ上或いは1つ下に項目を挿入する
- 挿入した項目を選択する
この手順に沿って記述したソースコードが次の通りです。
using System.Windows;
using System.Collections.ObjectModel;
namespace ListBoxSample
{
public partial class MainWindow : Window
{
ObservableCollection Items = new ObservableCollection();
public MainWindow()
{
InitializeComponent();
Items.Add(new Fruit { No = 1, Name = "Apple", Color = "Red" });
Items.Add(new Fruit { No = 2, Name = "Banana", Color = "Yellow" });
Items.Add(new Fruit { No = 3, Name = "Cherry", Color = "Red" });
Items.Add(new Fruit { No = 4, Name = "Kiwi", Color = "Green" });
Items.Add(new Fruit { No = 5, Name = "Orange", Color = "Orange" });
ListBox1.ItemsSource = Items;
}
private void btnUp_Click(object sender, RoutedEventArgs e)
{
//選択項目がない場合は処理せず戻し
if (ListBox1.SelectedItems.Count == 0) return;
//選択項目が先頭の場合は処理せず戻し
if (ListBox1.SelectedIndex == 0) return;
//選択されている項目を取得
var selectItem = (Fruit)ListBox1.SelectedItem;
var selectedIndex = ListBox1.SelectedIndex;
//選択されている項目を削除
Items.RemoveAt(selectedIndex);
//削除した項目の1つ上に新たに項目を挿入する
Items.Insert(selectedIndex - 1, selectItem);
//移動した項目を選択
ListBox1.SelectedIndex = selectedIndex - 1;
}
private void btnDown_Click(object sender, RoutedEventArgs e)
{
//選択項目がない場合は処理せず戻し
if (ListBox1.SelectedItems.Count == 0) return;
//選択項目が末尾の場合は処理せず戻し
if (ListBox1.SelectedIndex == ListBox1.Items.Count - 1) return;
//選択されている項目を取得
var selectItem = (Fruit)ListBox1.SelectedItem;
var selectedIndex = ListBox1.SelectedIndex;
//選択されている項目を削除
Items.RemoveAt(selectedIndex);
//削除した項目の1つ上に新たに項目を挿入する
Items.Insert(selectedIndex + 1, selectItem);
//移動した項目を選択
ListBox1.SelectedIndex = selectedIndex + 1;
}
}
}
上記のコードを実行すると次のような結果になります。
スクロールバーを付ける
ListBox にスクロールバーを表示するには、ScrollViewer クラスを使います。
縦スクロールを表示するなら HorizontalScrollBarVisibility プロパティを Visible にし、縦スクロールを表示するなら VerticalScrollBarVisibility プロパティを Visible にします。
<Window
x:Class="ListBoxSample.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:local="clr-namespace:ListBoxSample"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="400"
Height="250"
mc:Ignorable="d">
<Grid>
<ListBox
Name="ListBox1"
Margin="10"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="5,0,5,0" Text="{Binding No}" />
<TextBlock Margin="5,0,5,0" Text="{Binding Name}" />
<TextBlock Margin="5,0,5,0" Text="{Binding Color}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
スクロールバーを操作できるように、ソースコードはコレクションの数を増やしておきます。
using System.Windows;
using System.Collections.ObjectModel;
namespace ListBoxSample
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var Items = new ObservableCollection();
Items.Add(new Fruit { No = 1, Name = "Apple", Color = "Red" });
Items.Add(new Fruit { No = 2, Name = "Banana", Color = "Yellow" });
Items.Add(new Fruit { No = 3, Name = "Cherry", Color = "Red" });
Items.Add(new Fruit { No = 4, Name = "Kiwi", Color = "Green" });
Items.Add(new Fruit { No = 5, Name = "Orange", Color = "Orange" });
Items.Add(new Fruit { No = 6, Name = "Strawberry", Color = "Red" });
Items.Add(new Fruit { No = 7, Name = "Peach", Color = "Pink" });
Items.Add(new Fruit { No = 8, Name = "Persimmon", Color = "YellowRed" });
Items.Add(new Fruit { No = 9, Name = "Blueberry", Color = "Purple" });
Items.Add(new Fruit { No = 10, Name = "Mango", Color = "Orange" });
ListBox1.ItemsSource = Items;
}
}
}
上記のコードを実行すると次のような結果になります。
まとめ
この記事では ListBox(リストボックス)の基本的な書き方と利用頻度が多い使い方を紹介しました。
WPF でデータを表示したい場合には ListBox を使用する事が多いので、ぜひ扱えるようになっておきましょう。
リストボックスを使ってドラッグ&ドロップしたい方は、こちらの記事を参考にしてみてください。
以上、最後まで読んで頂きありがとうございました。