C#WPFの道#21!ListBoxの書き方と使い方を解りやすく解説

当サイトではアフィリエイト広告を利用しています。

WPF

ListBox(リストボックス)とは?

ListBoxとは,一覧表示から任意の行を選択できるコントロールです。選択は単一でも,複数でも可能です。

ListBoxの使い方

ListBox上のコントロールを追加して並べることもできますが,基本的には一覧表示に使うので,データバインディングをして使うことになると思います。データバインディングの方法は,ListViewやComboBoxと同様にItemTemplateやDataTemplateを使って実装します。

SelectionMode

ListViewやComboBoxと異なる点として,SelectionModeというプロパティがあるので,その部分を説明します。SelectionModeは,ListBoxの項目を単一で選択させるか,複数選択を可能とするかの設定です。設定は次の3パターンになります。

Single

1つの項目のみ選択可能となります。

Extended

キーボードのControlキーや,Shiftキーを押している最中にクリックをすると,複数選択が可能となります。使い方はExcelの行選択をするときと同じで,Controlを押しながらであれば,クリックした行を選択でき,Shiftを押している場合は,最初に選択した行から,その次に選択した行までを,まとめて選択することができます。

Multiple

キーボードのキーを押さなくても,複数選択が可能となります。クリックした行が選択状態になり,もう一度クリックすると,選択が解除されます。

サンプルコード

<Window x:Class="WPF021.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:WPF021"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="300">
    <Grid>
        <StackPanel>
            <ListBox x:Name="MyListBox"
                     HorizontalAlignment="Left"
                     VerticalAlignment="Top"
                     Margin="10"
                     Width="260"
                     Height="180">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <Image Source="{Binding FileName}"
                                   Width="50"
                                   Height="50"
                                   Margin="10"
                                   />
                            <TextBlock Text="{Binding Name}"
                                       Margin="10"
                                       />
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
            <StackPanel Orientation="Horizontal">
                <RadioButton x:Name="SingleRadioButton" Content="Single" Checked="RadioButton_Checked"/>
                <RadioButton x:Name="ExtendedRadioButton" Content="Extended" Checked="RadioButton_Checked"/>
                <RadioButton x:Name="MultipleRadioButton" Content="Multiple" Checked="RadioButton_Checked"/>
            </StackPanel>
            <Button FontSize="20"
                    Content="check"
                    Click="Button_Click"/>
        </StackPanel>
    </Grid>
</Window>
  • ItemTemplateとDataTemplateを使用して,ListBoxにデータバインディングするレイアウトを作成しています。
  • 1行分のレイアウトは画像と名前を表示するようにしています。
  • ListBoxの下に,ラジオボタンを3つ設置し,SelectionModeを選択できるようにしています。
  • RadioButtonの下にボタンを設置し,クリックイベントにブレークポイントを置くことで,ListBoxの選択状態のときの中身を確認するために使用します。
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;

namespace WPF021
{
    ///
    /// MainWindow.xaml の相互作用ロジック
    /// 
    public partial class MainWindow : Window
    {
        private ObservableCollection _dtos = new ObservableCollection();

        public MainWindow()
        {
            InitializeComponent();

            _dtos.Add(new Dto("Images/A.jpeg", "Shinichi ONO"));
            _dtos.Add(new Dto("Images/B.jpeg", "Jyunta INAMOTO"));
            _dtos.Add(new Dto("Images/C.jpeg", "Naotaro TAKAHARA"));
            MyListBox.ItemsSource = _dtos;
            SingleRadioButton.IsChecked = true;
        }

        private void RadioButton_Checked(object sender, RoutedEventArgs e)
        {
            if(SingleRadioButton.IsChecked.Value)
            {
                MyListBox.SelectionMode = SelectionMode.Single;
            }
            else if (ExtendedRadioButton.IsChecked.Value)
            {
                MyListBox.SelectionMode = SelectionMode.Extended;
            }
            else
            {
                MyListBox.SelectionMode = SelectionMode.Multiple;
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {

        }
    }

    public sealed class Dto
    {
        public Dto(string fileName, string name)
        {
            FileName = fileName;
            Name = name;
        }

        public string FileName { get; set; }
        public string Name { get; set; }
    }
}
  • 一番下に,別のクラスとしてDtoクラスを作成しています。内容は画面のファイル名と名称の2項目です。このクラスのリストをデータバインドします。
  • PrivateフィールドにDtoのリストを生成しています。
  • Dtoのリストに3件のデータを作成しています。
  • ListBoxのItemsSourceにDtoのリストを設定しています。
  • ラジオボタンの初期値はSingleを選択しています。
  • ラジオボタンのチェック状態変更イベントに応じて,ListBoxのSelectionModeを変更しています。

実行結果

  • Singleモードのときは1行しか選択できません。

  • Extendedモードのときは,ControlかShiftを押して複数選択が可能です。

Multipleモードのときは,キーボードを押さずにクリックのみで,複数選択が可能です。選択されている行をクリックすると,選択が解除されます。

選択中のSelectionItemsの中身

  • 「check」ボタンのクリックイベントにブレークポイントを置きます。
  • 3行目を選択した後,1行目を選択した状態で「check」ボタンを押下します。
  • ブレークポイントでデバッグが停止されている状態で,ListBoxのSelectedItemとSelectionItemsの中身を確認してみましょう。

  • SelectedItemには3行目の値が入っています。最初に選択された行が格納されていることがわかります。
  • SelectionItemsの中身には3行目,1行目の順番でデータが格納されています。行を選択した順番で格納されていることがわかります。