C#のWinFormsでListBoxのDataSourceを更新する方法

C# コンピュータ
C#

ユーザーが作成したクラスのオブジェクトをList<>で配列を作り、それをListBoxのDataSourceにセットしてみました。

ソースコード

namespace ListboxDataSrc;

public class BaseClass
{
    public virtual string Name {
        get {
            return "BaseClass";
        }
    }
    public virtual void exec() {
        MessageBox.Show(Name, "Message");
    }
}
public class AClass : BaseClass
{
    public override string Name {
        get{
            return "AClass";
        }
    }
    public override void exec()
    {
        MessageBox.Show(Name, "Message");
    }
}
public class BClass : BaseClass
{
    public override string Name {
        get{
            return "BClass";
        }
    }
    public override void exec()
    {
        MessageBox.Show(Name, "Message");
    }
}

public class DClass : BaseClass
{
    public override string Name {
        get{
            return "DClass";
        }
    }
    public override void exec()
    {
        MessageBox.Show(Name, "Message");
    }
}

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        var listbox = new ListBox {
            Location = new System.Drawing.Point(10, 10),
            Size = new System.Drawing.Size(400,300),
        };

        var list = new List<BaseClass>();
        list.Add(new BaseClass());
        list.Add(new AClass());
        list.Add(new BClass());

        var bs = new BindingSource();

        bs.DataSource = list;
        listbox.DataSource = bs;
        listbox.DisplayMember = "Name";
        

        var addBtn = new Button {
            Location = new System.Drawing.Point(420, 20),
            Size = new System.Drawing.Size(100,80),
            Text = "項目の追加"
        };
        addBtn.Click += (sender, e) => {
            list.Add(new DClass());
            bs.ResetBindings(false);
        };

        var execBtn = new Button {
            Location = new System.Drawing.Point(540, 20),
            Size = new System.Drawing.Size(100,80),
            Text = "実行"
        };
        execBtn.Click += (sender, e) => {
            var i = listbox.SelectedIndex;
            if (i < 0) return;
            list[i].exec();
        };

        Controls.Add(listbox);
        Controls.Add(addBtn);
        Controls.Add(execBtn);
        Size = new System.Drawing.Size(800, 600);
    }
}

実行

実行するとListBoxに3つの要素が追加されています。

「追加」ボタンを押すとListBoxに「DClass」が追加されます。

Listboxの「DClass」要素が選択された状態で「実行」ボタンをおすとメッセージボックスが表示されます。

説明

始めListBoxのDataSourceにデータソースとしてListオブジェクトを割り当てたところListBoxに表示されますが要素を追加することが出来ませんでした。調べたところBindingSourceオブジェクトを生成し、BindingSourceオブジェクトのDataSrouceプロパティにListオブジェクト割り当て、さらにListBoxのDataSrouceプロパティにBindingSourceオブジェクトを割り当てると良いようです。データソースのListオブジェクトに要素を追加しBindingSource.ResetBindings(false)を実行することでListBoxの内容が更新されました。

あと、データソースの要素用にClassの継承というのを使ってみました。このような使い方でよいのか不安ですが、とりあえず自分の意図した通りに動いてくれています。

コメント