Windows Form ComboBox.DataSource に紐づけた集合を更新する
DataSource
プロパティを使う場合のデータソース更新の反映方法をまとめてみた。
本音を言えば C# でも
#define
を使えるようになっていたことを発見したのがうれしくて作った気がする。
注意点は、どのキーワードよりも前に書かなければならないこと。有効範囲はファイル単位。
# define DEFINE1
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace WinFormAsync
{
public partial class UserControl1 : UserControl
{
private List<string> stringList = new List<string> { "abc", "123" };
// 2016-12-19 追記
// List<T> の代わりに System.ComponentModel.BindingList<T> を使えばリストを更新するだけでコントロールも更新されるようです。機能は少々ゴテっとしていますが。
// private BindingList<string> stringList = new BindingList<string> { "abc", "123" };
public UserControl1()
{
InitializeComponent();
comboBox1.DataSource = stringList;
}
private void button1_Click(object sender, EventArgs e)
{
# if DEFINE1
// 全体入れ替え - アイテムに x, y が追加される
// DataSource (List<string>) と ComboBox を直結
stringList.AddRange(new List<string> { "x", "y" });
// ComboBox を更新、null 代入が必要
comboBox1.DataSource = null;
comboBox1.DataSource = stringList;
# elif DEFINE2
// 全体入れ替え - アイテム x, y が追加される
// DataSource (List<string>) と ComboBox を直結
var newList = new List<string> { "x", "y" };
// ComboBox を更新
comboBox1.DataSource = newList;
# elif DEFINE3
//// 全体入れ替え - アイテムに def が追加される
// List<> と ComboBox の間に BindingSource をかます
var bindingSource1 = new BindingSource(stringList, "");
comboBox1.DataSource = bindingSource1;
// データソースに def を追加して
stringList.Add("def");
// ComboBox を更新
bindingSource1.ResetBindings(false);
# else
// 項目更新
// List<> と ComboBox の間に BindingSource をかます
var bindingSource1 = new BindingSource(stringList, "");
comboBox1.DataSource = bindingSource1;
stringList[0] = "ooo";
bindingSource1.ResetItem(0);
# endif
}
// 12-06-2016 追加
// string ではなくユーザデータを DataSource に。
private List<UserData> userDataList = new List<UserData>
{
new UserData { Id = 1, Name = "taro", Memo = "taromemo" },
new UserData { Id = 2, Name = "hanako", Memo = "hanakomemo"}
};
private void button2_Click(object sender, EventArgs e)
{
comboBox1.DataSource = userDataList;
comboBox1.ValueMember = "Memo";
comboBox1.DisplayMember = "Name";
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Debug.WriteLine(comboBox1.SelectedValue);
}
}
public class UserData
{
public int Id { get; set; }
public string Name { get; set; }
public string Memo { get; set; }
}
}
確認した環境
OS: 日本語 Windows 10 Home 64ビット
コンパイラ: Microsoft Visual Studio Community 2015 Update 3