none
コンボボックスについての問題です。 RRS feed

  • 質問

  • こんにちは、剣道です。
    また質問です。

    今、コンボボックス項目表示設定のクラスが有りまして。

    目的:
    例えば、フォーム上で、選択したコンボボックスの表示の値:"おはよう"、
    DBに登録の値は "1"になります。
    "こんにちは"→→ "2"
    "こんばんは"→→ "3"


    逆に、DBで取得した"1"なら、コンボボックスの表示の値:"おはよう"になります。

     

    下記は、コンボボックス用のデータクラス
         /// <summary>
        /// コンボボックス用のデータクラスです。
        /// </summary>
        public class ComboBoxItem
        {
            #region コンストラクタ
            /// <summary>
            /// コピーコンストラクタ
            /// </summary>
            /// <param name="name">コンボボックスに表示する名称</param>
            /// <param name="data">内部で保持するデータ</param>
            public ComboBoxItem(string name, object data)
            {
                // メンバ変数設定
                _name = name;                       // コンボボックスの名称
                _data = data;                         // 内部で保持するデータ
            }       
            #endregion       
           
            private string _name = "";                          // コンボボックスの名称
            private object _data = null;                        // 内部で保持するデータ
          

            #region プロパティ       
            public string Name
            {
                get
                {
                    return _name;
                }
                set
                {
                    _name = value;
                }
            }
           
            public object ItemData
            {
                get
                {
                    return _data;
                }
                set
                {
                    _data = value;
                }
            }
            #endregion


            #region メソッド - パブリック
            /// <summary>
            /// コンボボックスに表示する為の名称を取得します。
            /// </summary>
            /// <returns>コンボボックスに表示する名称</returns>
            public override string ToString()
            {
                return _name;
            }

            /// <summary>
            /// 内部で保持する値を文字列として取得します。
            /// </summary>
            /// <returns>内部で保持する値(文字列)</returns>
            public string GetStringValue()
            {
                return _data.ToString();
            }

            /// <summary>
            /// 内部で保持する値を文字列として取得します。
            /// </summary>
            /// <param name="index">取得する値のインデックス</param>
            /// <returns>内部で保持する値(文字列)</returns>
            public string GetStringValue(int index)
            {
                // オブジェクトチェック
                ArrayList list = (ArrayList)_data;

                // 範囲チェック
                if ((index < 0) ||
                    (index >= list.Count))
                {
                    throw new Exception(string.Format("インデックスが配列の境界外です。要素数:{0}、指定要素インデックス:{1}", list.Count, index));
                }

                return list[index].ToString();
            }

            /// <summary>
            /// 内部で保持する値を数値として取得します。
            /// </summary>
            /// <returns>内部で保持する値(数値)</returns>
            public int GetIntValue()
            {
                // オブジェクトチェック
                return int.Parse(_data.ToString());
            }
    ************************************************************************
    ************************************************************************
    今、DBへ登録の方は、うまくいきました。
    ComboBox1.Items.Add(new ComboBoxItem("おはよう","1"));
    ComboBox1.Items.Add(new ComboBoxItem("こんにちは","2"));
    ComboBox1.Items.Add(new ComboBoxItem("こんばんは","3"));

     

    ComboBoxItem cbI = (ComboBoxItem)ComboBox1.SelectedItem;
    cnI.ItemDataの値をDBに登録すれば、OKです。

    でもDBから取得した値は、コンボボックスに表示する方法が分からないです。
    ご教示よろしくお願いいたします。

     

     

     

    2008年4月24日 6:39

回答

  • コンボボックスのSelectedValueにItemDataを指定していませんか? もし指定しているのであれば、DBからの値をSelectedValueにセットすればOKです。
    2008年4月24日 7:01
    モデレータ

すべての返信

  • コンボボックスのSelectedValueにItemDataを指定していませんか? もし指定しているのであれば、DBからの値をSelectedValueにセットすればOKです。
    2008年4月24日 7:01
    モデレータ
  • trapemiyaさん

    返事が遅くなりまして、申し訳ございませんでした。

    コンボボックスのSelectedValueのプロパディ設定で、うまくいきました。

    解決しました。大変ありがとうございました。

     

     

    2008年4月24日 9:53
  • あれ?解決されたのですか。
    バインドされていないようですので、trapemiya さんの方法ではうまくいかないと思い、以下の返信を書いていました。
    一応、何かの参考になればと思いますので、返信させてもらいます。

     

    次のメソッドを ComboBoxItem クラスに加えてください。

     

    Code Snippet

    public override bool Equals(object obj)
    {
        ComboBoxItem item = obj as ComboBoxItem;
        if (item == null)
            return object.Equals(this._data, obj);
        else
            return object.Equals(this._data, item._data);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }

     

     

    すると、次のように表示項目を指定できるようになります。

     

    Code Snippet

    comboBox1.SelectedItem = new ComboBoxItem("ここの値は無視", "2");
    // または
    comboBox1.SelectedItem = "2";

     


    余談ですが、
    このクラス、無理に汎用性を持たせようとされている気が少しします。
    DBと関連するコンボボックスであれば、素直にバインドの仕組みを活用された方がよくはないでしょうか?
    すると trapemiya さんの方法が使えます。
    # いろいろ事情がお有りかと思いますので、あくまで余談です。

     

    Code Snippet

    private void button1_Click(object sender, EventArgs e)
    {
        DataTable greetings = new DataTable();
        greetings.Columns.Add("DbValue", typeof(string));
        greetings.Columns.Add("DisplayValue", typeof(object));
        greetings.Rows.Add(DBNull.Value, null);
        greetings.Rows.Add("1", "おはよう");
        greetings.Rows.Add("2", "こんにちは");
        greetings.Rows.Add("3", "こんばんは");
        greetings.Rows.Add("X", new GoodNight("abc"));
        comboBox1.ValueMember = "DbValue";
        comboBox1.DisplayMember = "DisplayValue";
        comboBox1.DataSource = greetings;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        MessageBox.Show(string.Format("{0}", comboBox1.SelectedValue));
    }

    private void button3_Click(object sender, EventArgs e)
    {
        comboBox1.SelectedValue = "3";
    }

    public class GoodNight
    {
        private string _target;
        public GoodNight(string target)
        { _target = target; }
        public override string ToString()
        { return _target + "さん、おやすみ"; }
    }

     

    2008年4月24日 11:18
  •  TH01 さんからの引用

    バインドされていないようですので、trapemiya さんの方法ではうまくいかないと思い、以下の返信を書いていました。
    一応、何かの参考になればと思いますので、返信させてもらいます。

     

    あっ、確かにそうですね。大変失礼いたしました。勘違いしておりました。ご指摘ありがとうございます。また、掲載されたコードは大変参考になりました。バインド以外はあまり使わないので新鮮でした。

     

    折角なのでバインドを使ったパターンです。

     

      BindingList<ComboBoxItem> bl = new BindingList<ComboBoxItem>();
      
      // comboBox1.Items.Add(new ComboBoxItem("おはよう", "1"));
      // comboBox1.Items.Add(new ComboBoxItem("こんにちは", "2"));
      // comboBox1.Items.Add(new ComboBoxItem("こんばんは", "3"));

       
       // 以下のパターンだとデータバインドしているため、SelectedValueが使える。
       bl.Add(new ComboBoxItem("おはよう", "1"));
       bl.Add(new ComboBoxItem("こんにちは", "2"));
       bl.Add(new ComboBoxItem("こんばんは", "3"));

       

       comboBox1.DataSource = bl;
       comboBox1.DisplayMember = "Name";
       comboBox1.ValueMember = "ItemData";

    2008年4月24日 15:37
    モデレータ