- PR -

コンボボックスのデータソース変更結果を即時反映させる方法

投稿者投稿内容
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-03-31 14:39
引用:

nanbuさんの書き込み (2006-03-31 14:23) より:

奇妙な質問ですね、、



本当に奇妙な質問になってしまいました。
テストは ListBox を使っていたので、てっきりオブジェクト連絡用のプロパティの
下にあるものだとばかり思っていました。
で、探してみたら無かったので質問したのですが、ComboBox には、DataSourceChangedイベントがあるんですね。

以上、見苦しい言い訳でした。
早速、確認してみます。_(_*_)_ ヘヘー
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-03-31 14:47
引用:

nanbuさんの書き込み (2006-03-31 12:30) より:

null代入をコメントアウトすると、
DataSourceChangedイベントは発生しているのかな?



コード:
        private void ComboBox_DataSourceChanged(object sender, EventArgs e) {
            System.Diagnostics.Debug.WriteLine("データソースが変わった!!");
        }



とした場合、null をコメントアウトすると出力ウィンドウには何も表示されません。
null を渡してやると、「データソースが変わった!!」と2行表示される訳ですが。
これは、null の分を含めて2行ということなのでしょうか。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-03-31 14:57
引用:

R・田中一郎さんの書き込み (2006-03-31 14:05) より:

コンボボックスの変更と共に、新しいデータを this.selectedItems にセットし、
ボタンを押すことで、this.listBox.DataSource = this.selectedItems; するようにしてみた訳です。


もっと単純にして問題の切り分けをしてみましょう。

コード:

    public class WankumaItem {

      #region コンストラクタ 

        public WankumaItem(object value, string text) {
            this._Value = value;
            this._Text  = text;
        }

      #endregion

      #region Value プロパティ 

        private object _Value;

        public object Value {
            get {
                return this._Value; 
            }
        }

      #endregion

      #region Text プロパティ 

        private string _Text;

        public string Text {
            get {
                return this._Text;
            }
        }

      #endregion

      #region ToString メソッド (override) 

        public override string ToString() {
            return this.Value.ToString() + ":" + this.Text;
        }

      #endregion

    }


まあ似たような Item と Collection のクラスがありまして、

コード:

    public partial class Form1 : Form {

        public Form1() {
            this.InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e) {
            WankumaCollection wankumas = new WankumaCollection();
            wankumas.Add(new WankumaItem(0, "中博俊"));
            wankumas.Add(new WankumaItem(1, "じゃんぬねっと"));
            wankumas.Add(new WankumaItem(2, "Jitta"));

            this.comboBox1.DataSource = wankumas;
            this.comboBox1.ValueMember = "Value";
            this.comboBox1.DisplayMember = "Text";
        }

        private void button1_Click(object sender, EventArgs e) {
            WankumaCollection wankumas = new WankumaCollection();
            wankumas.Add(new WankumaItem(3, "trapemiya"));
            wankumas.Add(new WankumaItem(4, "επιστημη"));
            wankumas.Add(new WankumaItem(5, "やねうらお"));

            this.comboBox1.DataSource = wankumas;
        }
    }


こういう単純なコードから開始してみるとか。

引用:

これの違いでしょうか。


これは考えられないです。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-03-31 15:01
おっと、入れ違い...

引用:

R・田中一郎さんの書き込み (2006-03-31 14:47) より:

null を渡してやると、「データソースが変わった!!」と2行表示される訳ですが。
これは、null の分を含めて2行ということなのでしょうか。


それを確認するために、

  this.listBox.DataSource = null;

と、DataSourceChanged イベントの先頭にブレーク ポイントを設定してください。
そして、DataSource = null の場所でブレークしたら F10 でステップ実行しましょう。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-03-31 17:10
原因がわかりました。

引用:

じゃんぬねっとさんの書き込み (2006-03-31 14:57) より:

コード:

        private void button1_Click(object sender, EventArgs e) {
            WankumaCollection wankumas = new WankumaCollection();
            wankumas.Add(new WankumaItem(3, "trapemiya"));
            wankumas.Add(new WankumaItem(4, "επιστημη"));
            wankumas.Add(new WankumaItem(5, "やねうらお"));

            this.comboBox1.DataSource = wankumas;
        }
    }



こういう単純なコードから開始してみるとか。



WankumaCollection wankumas = new WankumaCollection();

ここで新しいインスタンスを作っていますが、僕のは同じインスタンスを Clear() し
ています。
上記のコードを実行させて正常に動作することを確認後、wankumas をフィールド変数
にして、ボタンクリック時に Clear() にすると画面が切り替わらなくなりました。

引用:

じゃんぬねっとさんの書き込み (2006-03-31 15:01) より:

引用:

R・田中一郎さんの書き込み (2006-03-31 14:47) より:

null を渡してやると、「データソースが変わった!!」と2行表示される訳ですが。
これは、null の分を含めて2行ということなのでしょうか。


それを確認するために、

  this.listBox.DataSource = null;

と、DataSourceChanged イベントの先頭にブレーク ポイントを設定してください。
そして、DataSource = null の場所でブレークしたら F10 でステップ実行しましょう。



ありがとうございます。
やはり null で1回でした。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-03-31 17:30
引用:

R・田中一郎さんの書き込み (2006-03-31 17:10) より:

ここで新しいインスタンスを作っていますが、僕のは同じインスタンスを Clear() し
ています。
上記のコードを実行させて正常に動作することを確認後、wankumas をフィールド変数
にして、ボタンクリック時に Clear() にすると画面が切り替わらなくなりました。


なるほど、理解できました。(;^-^)

Clear した場合は結局同じインスタンスを参照しているため、再バインドにならない。
Clear メソッドの代わりに新しいインスタンスを生成すれば、違うものが参照されるため、再バインドになる。

null を設定するのは、参照を変えてバインドを発生させるためで、
1 回余分に DataSourceChanged イベントが起きますね。
気になるならば、別の新しいインスタンスを使えば良いことになりますね。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-03-31 17:53
引用:

じゃんぬねっとさんの書き込み (2006-03-31 17:30) より:

Clear した場合は結局同じインスタンスを参照しているため、再バインドにならない。
Clear メソッドの代わりに新しいインスタンスを生成すれば、違うものが参照されるため、再バインドになる。

null を設定するのは、参照を変えてバインドを発生させるためで、
1 回余分に DataSourceChanged イベントが起きますね。
気になるならば、別の新しいインスタンスを使えば良いことになりますね。



そうですね。
じゃんぬねっとさんのサンプルの様に、内容が変わるたびに new する方がわかりや
すいですね。

ありがとうございました。
Kazuki
ぬし
会議室デビュー日: 2004/10/13
投稿数: 298
投稿日時: 2006-04-01 12:22
コンボボックスと同期を取りたいならBindingList<T>とかにしちゃうのも手

スキルアップ/キャリアアップ(JOB@IT)