【C#】【Form】ComboBox ~ あれこれ編 ~

■ はじめに

https://blogs.yahoo.co.jp/dk521123/30294576.html
の続き。

今回は、さまざまな使い方をまとめる。

■ 複数コンボボックスを連動させるには

 * 以下の関連記事を参照のこと
ComboBox ~ 複数コンボボックスを連動させるには ~
https://blogs.yahoo.co.jp/dk521123/37979233.html

■ DBからとってきた値をComboBoxに反映させる

サンプル

combox1.DataSource = [DBからとってきた値(例:List<T>)];
combox1.ValueMember = "id"; // 値
combox1.DisplayMember = "name"; // 表示

■ DataBindingを使用して表示する

 * 上述のサンプルと合わせれば、enumクラスを使って、もっといいサンプルができそう(課題)

サンプル

クラス(SampleItem.cs)
// DataBindingのValueMember、DisplayMemberを設定するためのプロパティを定義するクラス

public class SampleItem
{
    private string value = string.Empty;
    private string name = string.Empty;

    // ValueMemberに設定する文字列
    public string Value
    {
        set
        {
            this.value = value;
        }
        get
        {
            return this.value;
        }
    }

    // DisplayMemberに設定する文字列
    public string Name
    {
        set
        {
            this.name = value;
        }
        get
        {
            return this.name;
        }
    }
}
画面側
private void Form1_Load(object sender, EventArgs e)
{
    List<SampleItem> items = new List<SampleItem>
    {
        new SampleItem() {Name = "男", Value = "1"},
        new SampleItem() {Name = "女", Value = "2"},
    };

    this.comboBox1.DataSource = items;
}

■ 指定した文字列で始まる最初の項目を検索し該当するIndexを取得

 * ComboBox.FindString() / ComboBox.FindStringExact() を使用する

サンプル

private void Form1_Load(object sender, EventArgs e)
{
    var programs = {"C#", "Java", "HTML", "C++", "PHP", "XHTML"};
    this.comboBox1.Items.AddRange(programs);
}
    

private void button1_Click(object sender, EventArgs e)
{
    var index = this.comboBox1.FindStringExact("HTML");
    this.comboBox1.SelectedIndex = index;
}

参考資料

http://hiros-dot.net/VBNET2003/Control/ComboBox/ComboBox08.htm
http://gigasmegas.com/?p=1187

enumをBindingSourceに通して、ComboBoxに反映させる

 * ほかのコントロール(ListBoxなど)にも使えると思う

準備

 * ComboBox : 1
 * BindingSource : 1
 * Resource : 1 (表示用)

サンプル

public enum Sex { Male, Female }

KeyValuePair<string, Sex>[] sex
    = new KeyValuePair<string, Sex>[]
    {
        new KeyValuePair<string, Sex>(Resource.Male, Sex.Male),
        new KeyValuePair<string, Sex>(Resource.Female, Sex.Female)
    };

private void Form1_Load(object sender, EventArgs e)
{
    // BindingSourceにKeyValuePairを連結
    this.bindingSource.DataSource = sex;

    // ComboBoxにBindingSourceを連結
    comboBox.DataSource = this.bindingSource;
    comboBox.ValueMember = "Value"; // 値
    comboBox.DisplayMember = "Key"; // 表示
}

Resource.resx

名前     値
---------------
Male  男性
Female 女性

参考資料

http://hiros-dot.net/CS2005/Control/BindingSource/BindingSource03.htm
http://d.hatena.ne.jp/siokoshou/20070627

enum値をそのまま、ComboBoxに反映させる

 * ほかのコントロール(ListBoxなど)にも使えると思う

サンプル

public enum Sex { Male, Female }

private void Form1_Shown(object sender, EventArgs e)
{
   this.comboBox1.DataSource = Enum.GetValues(typeof(Sex));
}

参考資料

http://d.hatena.ne.jp/siokoshou/20070627

■ 西暦・和暦混合のコンボボックスを作成する

private void Form1_Load(object sender, EventArgs e)
{
    CultureInfo culture = new CultureInfo("ja-JP", true);
    culture.DateTimeFormat.Calendar = new JapaneseCalendar();
    
    DateTime date = DateTime.Now;
    var list = new List<KeyValuePair<int, string>>();
    for (int i = 0; i < 10; i++)
    {
        DateTime value = date.AddYears(-i);
        string display = 
            value.ToString("yyyy年") +
            value.ToString("(ggyy年)", culture);
        var keyValue =
            new KeyValuePair<int, string>(value.Year, display);
        list.Add(keyValue);
    }

    this.comboBox1.DataSource = list;
    this.comboBox1.ValueMember = "Key";
    this.comboBox1.DisplayMember = "Value";
}

private void button1_Click(object sender, EventArgs e)
{
    this.label1.Text = this.comboBox1.SelectedValue;
}

■ 描画パフォーマンスを上げるには

問題点

 * ComboBoxの追加する項目が多ければ多いほど どチラツキが発生

解決策

 * BeginUpdateメソッド・EndUpdateメソッドの利用する

サンプル

// BeginUpdate()を使用して、再描画を禁止する
this.comboBox1.BeginUpdate();

// 10000アイテム追加する
for (int i = 0; i < 10000; i++)
{
  this.comboBox1.Items.Add(i);
}

// 項目の追加後に EndUpdate()を実行して、再描画する
this.comboBox1.EndUpdate();

参考文献

http://dobon.net/vb/dotnet/control/lbitemsadd.html
http://www.atmarkit.co.jp/fdotnet/dotnettips/648beginupdate/beginupdate.html
http://joomla.hiros-dot.net/windows-/2010-05-11-04-02-45/combobox/42-2010-06-04-16-48-58.html

■ オートコンプリート機能

以下の記事を参照のこと
https://blogs.yahoo.co.jp/dk521123/29586032.html

関連記事

Windows Form ~ 目次 ~

https://blogs.yahoo.co.jp/dk521123/8054245.html

ComboBox ~ 複数コンボボックスを連動させるには ~

https://blogs.yahoo.co.jp/dk521123/37979233.html

ComboBox ~ 基本編 ~

https://blogs.yahoo.co.jp/dk521123/30294576.html

オートコンプリート機能

https://blogs.yahoo.co.jp/dk521123/29586032.html