■ はじめに
複数コンボボックスを連動させることを考える 色々なスマートな方法があると思うが、オーソドックスに実装する
例
* 地方-都道府県-市・区 + 地方:関東、関西、東北、、、 + 都道府県:東京、大阪、、、 + 市・区:港区、横浜市、、、
■ 注意点
【1】データバインド時、 DisplayMemer, ValueMemberを事前に設定する 【2】TextChangedイベントで行う
【1】データバインド時、 DisplayMemer, ValueMemberを事前に設定する
https://netplanetes.wordpress.com/2010/04/20/comboboxforms-%E3%81%AE-datasource-%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AE%E6%B3%A8%E6%84%8F%E7%82%B9/より抜粋 ~~~~~~~~ DisplayMember, ValueMember をセットする前に DataSource にバインドすると、 SelectedIndexChanged イベントが起動されて ComboBox.SelectedValue の値が想定した値(ValueMember) ではなく、 バインドしている現在選択されているオブジェクトそのものになってしまいます。 ~~~~~~~~ => これで例外になり落ちた
【2】TextChangedイベントで行う
SelectedIndexChanged イベント や SelectionChangeCommitted イベント だと 変更していなくても、イベント が走ってしまう
■ サンプル
using System; using System.Data; using System.Windows.Forms; namespace SampleForm { public partial class Form1 : Form { private DataTable dataTable; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { dataTable = new DataTable("Japan"); dataTable.Columns.Add("area", typeof(string)); dataTable.Columns.Add("prefecture", typeof(string)); dataTable.Columns.Add("city", typeof(string)); dataTable.Rows.Add("Kanto", "Tokyo", "Setagaya"); dataTable.Rows.Add("Kanto", "Tokyo", "Shibuya"); dataTable.Rows.Add("Kanto", "Tokyo", "Nakano"); dataTable.Rows.Add("Kanto", "Kanagawa", "Yokohama"); dataTable.Rows.Add("Kanto", "Kanagawa", "Kawasaki"); dataTable.Rows.Add("Kanto", "Saitama", "Saitama"); dataTable.Rows.Add("Kanto", "Saitama", "Fukaya"); dataTable.Rows.Add("Kanto", "Saitama", "Koshigaya"); dataTable.Rows.Add("Kanto", "Saitama", "Kawaguchi"); dataTable.Rows.Add("Kyushu", "Fukuoka", "Fukuoka"); dataTable.Rows.Add("Kyushu", "Nagasaki", "Nagasaki"); dataTable.Rows.Add("Kyushu", "Kagoshima", "Kagoshima"); var resultDataTableForArea = dataTable.DefaultView.ToTable(true, new string[] { "area" }); this.comboBox1.DisplayMember = "area"; this.comboBox1.ValueMember = "area"; this.comboBox1.DataSource = resultDataTableForArea; this.comboBox1.SelectedIndex = 0; this.InitializePrefectureComboBox(); this.InitializeCityComboBox(); } private void InitializePrefectureComboBox() { var resultDataTableForPrefecture = dataTable.AsEnumerable().Where( row => row.Field<string>("area") == this.comboBox1.SelectedValue.ToString()) .AsDataView().ToTable(true, new string[] { "area", "prefecture" }); this.comboBox2.DisplayMember = "prefecture"; this.comboBox2.ValueMember = "prefecture"; this.comboBox2.DataSource = resultDataTableForPrefecture; this.comboBox2.SelectedIndex = 0; } private void InitializeCityComboBox() { var resultDataTableForCity = dataTable.AsEnumerable().Where( row => row.Field<string>("area") == this.comboBox1.SelectedValue.ToString() && row.Field<string>("prefecture") == this.comboBox2.SelectedValue.ToString()) .AsDataView().ToTable(true, new string[] { "area", "prefecture", "city" }); this.comboBox3.DisplayMember = "city"; this.comboBox3.ValueMember = "city"; this.comboBox3.DataSource = resultDataTableForCity; this.comboBox3.SelectedIndex = 0; } private void comboBox1_TextChanged(object sender, EventArgs e) { this.InitializePrefectureComboBox(); this.InitializeCityComboBox(); } private void comboBox2_TextChanged(object sender, EventArgs e) { this.InitializeCityComboBox(); } } }
参考文献
https://netplanetes.wordpress.com/2010/04/20/comboboxforms-%E3%81%AE-datasource-%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AE%E6%B3%A8%E6%84%8F%E7%82%B9/http://www.moonmile.net/blog/archives/2412
関連記事
Windows Form ~ 目次 ~
https://blogs.yahoo.co.jp/dk521123/8054245.htmlコンボボックス関連
ComboBox ~ 基本編 ~https://blogs.yahoo.co.jp/dk521123/30294576.html
ComboBox ~ あれこれ編 ~
https://blogs.yahoo.co.jp/dk521123/20513549.html
その他
DataTable ~ DISTINCT / 重複した値を省くには... ~https://blogs.yahoo.co.jp/dk521123/14321146.html
DataTable ~ DataTable で Linq する ~
https://blogs.yahoo.co.jp/dk521123/37976709.html