目的
- ComboBoxの選択された入力を
ComboBox.SelectedIndex
で受け取りたくない! - ComboBoxに表示される文字列ではなく,それに対応した他のデータを受け取りたい!
ComboBox.SelectedIndex
は何が悪い?
- コンボボックスの内容の順序に依存してしまう(中身の順序が崩れると整合性が保てない).
- 数字しか取れないため,データのリンクが配列やリストに依存してしまう.
仕様
今回は,次のような仕様を考えた場合の実装をします.
-
Dictionary
のKey
はstring
とし,value
はClass User
とします.Dictionary<string, User>
- キーは常に固有な ID をもちます.(重複しません)
今回のFooクラスは次のようなクラスとします.
public class User
{
public string Name { get; set; }
public string Country { get; set; }
public User(string name, string country)
{
Name = name;
Country = country;
}
}
Dictionaryの定義
以下のような,string
をキー,Foo
を値としたDictionary
クラスを定義し,内容を追加します.
private Dictionary<string, User> UsersDict = new Dictionary<string, User>();
// FooDictに内容を追加
Choises.Add("a", new User("Alice", "United States"));
Choises.Add("b", new User("Bob", "Brazil"));
Choises.Add("c", new User("Carol", "Germany"));
ComboBoxのDataSourceにデータをセットする
FoosForComboBox
は,ComboBox
で表示するための文字列と,その表示された文字列から取得したいIDを取り出すための,Dictionary
を作成しています.
次に,foreach
を使い,FoosForComboBox
に対してfooクラスのキー(ID)と,Foo
クラスのName
を追加します.これによって,ComboBox
に名前が表示され,選択したときにIDの値を取得できるようになります.
そして,comboBox1.DisplayMember = "Value";
comboBox1.ValueMember = "Key";
これに寄って,表示するメンバを値に,値のメンバをキーにするようにします.
最後に,ComboBox
のDataSource
に対して,作成したFoosForComboBox
をリストにして指定します.comboBox1.DataSource = FoosForComboBox.ToList();
次のようになります.
private void setComboBoxUsers()
{
// Dictionary<ID, ComboBoxに表示したい文字列>
Dictionary<string, string> ComboBoxUsers = new Dictionary<string, string>();
foreach (KeyValuePair<string, Choise> user in Users)
{
ComboBoxUsers.Add(user.Key, user.Value.Name);
}
comboBox1.DisplayMember = "Value";
comboBox1.ValueMember = "Key";
comboBox1.DataSource = ComboBoxUsers.ToList();
}
IDからクラスの他のメンバ変数を取得する
最後に,comboBox1.SelectedValue.ToString()
からkey
となるid
を取得して,UsersDict
の中身を参照することができました!
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string id = comboBox1.SelectedValue.ToString();
Console.WriteLine($"Selected Name: {UsersDict[id].Name}");
Console.WriteLine($"Selected Country: {UsersDict[id].Country}");
}