- - PR -
DataBindingした場合の値の変更
| 投稿者 | 投稿内容 | ||||
|---|---|---|---|---|---|
|
投稿日時: 2004-10-31 18:51
toppoです。
自作クラスのプロパティと、テキストボックスをデータバインドした場合に、 GUIからの値の変更を自作クラス自身が知る事は出来るのでしょうか? というのも、 txtBox1.DataBindings.Add( "Text", this.Hoge, "Value" ); というように、Hogeクラス(FormにはHogeというHogeクラスの インスタンスにアクセスするプロパティが用意してあります。) のValueプロパティとバインドしています。 GUIから値を変更しても、HogeクラスのValueプロパティの setブロックに処理が入らないようです。 Hogeクラスが内部で状態の変更を受けて処理をしたいのですが、 状態の変更を知る方法はあるのでしょうか? よろしくお願いします。 [ メッセージ編集済み 編集者: toppo 編集日時 2004-10-31 18:51 ] | ||||
|
投稿日時: 2004-11-01 00:15
toppoです。
自己レスです。 値の変更を知りたいという事でしたが、 DataBindingをしたときの動作が良く分からなくなってきました。 以下ソースを示します。 using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; namespace WindowsApplication1 { /// <summary> /// Form1 の概要の説明です。 /// </summary> public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.ComboBox comboBox1; private ValueClass valueClass = new ValueClass(); private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button2; public ValueClass DataSorce { get{ return valueClass; } set{ valueClass = value;} } /// <summary> /// 必要なデザイナ変数です。 /// </summary> private System.ComponentModel.Container components = null; public Form1() { // // Windows フォーム デザイナ サポートに必要です。 // InitializeComponent(); // コンボボックスへの設定 this.comboBox1.DataSource = ComboValueClass.ComboList; this.comboBox1.ValueMember = ComboValueClass.ValueMenberName; this.comboBox1.DisplayMember = ComboValueClass.DisplayMenberName; // テキストボックスにバインド this.textBox1.DataBindings.Add( "Text", this.DataSorce, "Hoge" ); // コンボボックスにバインド this.comboBox1.DataBindings.Add( "SelectedValue", this.DataSorce, "Foo" ); } /// <summary> /// 使用されているリソースに後処理を実行します。 /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows フォーム デザイナで生成されたコード /// <summary> /// デザイナ サポートに必要なメソッドです。このメソッドの内容を /// コード エディタで変更しないでください。 /// </summary> private void InitializeComponent() { this.textBox1 = new System.Windows.Forms.TextBox(); this.comboBox1 = new System.Windows.Forms.ComboBox(); this.button1 = new System.Windows.Forms.Button(); this.button2 = new System.Windows.Forms.Button(); this.SuspendLayout(); // // textBox1 // this.textBox1.Location = new System.Drawing.Point(40, 24); this.textBox1.Name = "textBox1"; this.textBox1.TabIndex = 0; this.textBox1.Text = ""; // // comboBox1 // this.comboBox1.Location = new System.Drawing.Point(48, 88); this.comboBox1.Name = "comboBox1"; this.comboBox1.Size = new System.Drawing.Size(121, 20); this.comboBox1.TabIndex = 1; // // button1 // this.button1.Location = new System.Drawing.Point(56, 160); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(136, 23); this.button1.TabIndex = 2; this.button1.Text = "DataSorceの値を表示"; this.button1.Click += new System.EventHandler(this.button1_Click); // // button2 // this.button2.Location = new System.Drawing.Point(56, 200); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(136, 23); this.button2.TabIndex = 3; this.button2.Text = "DataSorceに値を設定"; this.button2.Click += new System.EventHandler(this.button2_Click); // // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(5, 12); this.ClientSize = new System.Drawing.Size(292, 266); this.Controls.Add(this.button2); this.Controls.Add(this.button1); this.Controls.Add(this.comboBox1); this.Controls.Add(this.textBox1); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); } #endregion /// <summary> /// アプリケーションのメイン エントリ ポイントです。 /// </summary> [STAThread] static void Main() { Application.Run(new Form1()); } private void button1_Click(object sender, System.EventArgs e) { MessageBox.Show( this.DataSorce.Hoge ); MessageBox.Show( this.DataSorce.Foo ); } private void button2_Click(object sender, System.EventArgs e) { this.DataSorce.Hoge = "変更しました。"; this.DataSorce.Foo = "03"; this.Refresh(); this.comboBox1.Refresh(); this.textBox1.Refresh(); // this.comboBox1.Visible = false; // this.comboBox1.Visible = true; // this.textBox1.Visible = false; // this.textBox1.Visible = true; } /// <summary> /// コンボボックスの要素を表すクラス /// </summary> public class ComboValueClass { /// <summary> /// ValueMember対応プロパティ名称 /// </summary> private static string valueMemberName = "Code"; public static string ValueMenberName { get{ return valueMemberName;} } /// <summary> /// DisplayMenber対応プロパティ名称 /// </summary> private static string displayMemberName = "Name"; public static string DisplayMenberName { get{ return displayMemberName;} } /// <summary> /// リストクラス保持配列 /// </summary> private static IList list = null; public static IList ComboList { get { if ( list == null ) { list = new ArrayList(); list.Add( new ComboValueClass( "01", "Test01" ) ); list.Add( new ComboValueClass( "02", "Test02" ) ); list.Add( new ComboValueClass( "03", "Test03" ) ); list.Add( new ComboValueClass( "04", "Test04" ) ); } return list; } } // コード private string code_; // 名称 private string name_; /// <summary> /// コンストラクタ /// </summary> public ComboValueClass( string code, string name ) { this.code_ = code; this.name_ = name; } /// <summary> /// コードの取得及び設定 /// </summary> public string Code { get{ return this.code_; } set{ this.name_ = value; } } /// <summary> /// 名称の取得及び設定 /// </summary> public string Name { get{ return this.name_; } set{ this.name_ = value; } } } /// <summary> /// ValueClass の概要の説明です。 /// </summary> public class ValueClass { private string hoge = "初期値"; private string foo = string.Empty; public ValueClass() { } public string Hoge { get { return hoge; } set { hoge = value; } } public string Foo { get { return foo; } set { foo = value; } } } } } 上記のソースを実行して、[DataSorceの値を設定]ボタンを押しても 表示上変わりません。[DataSorceの値を表示]ボタンを押すと、 ちゃんと設定されています。 Refresh()をしても、ちゃんと表示されず、 Visible = false; Visible = true; とすると、ちゃんと表示されます。 ただ、Visibleをfalse->trueとするなんていうのは、 気持ち悪いソースですよね。 直ぐに表示を反映させるには何か記述が足りないのか、 それとも、こうするしかないのでしょうか? ご存知の方、是非ご教授下さい。 よろしくお願いします。 | ||||
|
投稿日時: 2004-11-01 08:52
経験では、
Foo クラスの Bar プロパティをバインドするときは public event EventHandler BarChanged が必要そうです。
これで、プロパティ Bar をうまくバインドできると思います。 | ||||
|
投稿日時: 2004-11-01 10:55
toppoです。
にしざきさん。ありがとうございます。 これならFooの変化に対して、外部から、処理を記述する事ができますね。 私の投稿を見直していたのですが、質問内容が1つに絞れていませんでした。 最初に投稿した問題については、私の勘違いでした。 返信しようと試みてくれていた方には大変失礼致しました。 ですので、1つめの質問及び、文中のソースコメントは無視してください。 問題は2つめの質問で、バインド先のオブジェクトの内部状態が変わったときに、 表示が直ぐに変わってくれないという問題です。 未だに、良い解決法が分からない状態です。 宜しくお願いします。 | ||||
|
投稿日時: 2004-11-01 12:20
南部です。 にしざきさんの投稿で、解決済みと思われますが? | ||||
|
投稿日時: 2004-11-01 13:46
toppoです。
私、何か勘違いしているでしょうか? 以下のように変更してみましたが、 最初に、[DataSourceに値を設定]ボタンを押しても、 内部の値は変わっているのに、表示が変わりませんでした。 何か不足しているのでしょうか? this.comboBox1.Visible = false; this.comboBox1.Visible = true; this.textBox1.Visible = false; this.textBox1.Visible = true; のようにすると、直ぐに反映されるのは、 2004-11-01 00:15の投稿時と変わっていません。 using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; namespace WindowsApplication1 { /// <summary> /// Form1 の概要の説明です。 /// </summary> public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.ComboBox comboBox1; private ValueClass valueClass = new ValueClass(); private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button2; public ValueClass DataSorce { get{ return valueClass; } set{ valueClass = value;} } /// <summary> /// 必要なデザイナ変数です。 /// </summary> private System.ComponentModel.Container components = null; public Form1() { // // Windows フォーム デザイナ サポートに必要です。 // InitializeComponent(); // コンボボックスへの設定 this.comboBox1.DataSource = ComboValueClass.ComboList; this.comboBox1.ValueMember = ComboValueClass.ValueMenberName; this.comboBox1.DisplayMember = ComboValueClass.DisplayMenberName; // テキストボックスにバインド this.textBox1.DataBindings.Add( "Text", this.DataSorce, "Hoge" ); // コンボボックスにバインド this.comboBox1.DataBindings.Add( "SelectedValue", this.DataSorce, "Foo" ); } /// <summary> /// 使用されているリソースに後処理を実行します。 /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows フォーム デザイナで生成されたコード /// <summary> /// デザイナ サポートに必要なメソッドです。このメソッドの内容を /// コード エディタで変更しないでください。 /// </summary> private void InitializeComponent() { this.textBox1 = new System.Windows.Forms.TextBox(); this.comboBox1 = new System.Windows.Forms.ComboBox(); this.button1 = new System.Windows.Forms.Button(); this.button2 = new System.Windows.Forms.Button(); this.SuspendLayout(); // // textBox1 // this.textBox1.Location = new System.Drawing.Point(40, 24); this.textBox1.Name = "textBox1"; this.textBox1.TabIndex = 0; this.textBox1.Text = ""; // // comboBox1 // this.comboBox1.Location = new System.Drawing.Point(48, 88); this.comboBox1.Name = "comboBox1"; this.comboBox1.Size = new System.Drawing.Size(121, 20); this.comboBox1.TabIndex = 1; // // button1 // this.button1.Location = new System.Drawing.Point(56, 160); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(136, 23); this.button1.TabIndex = 2; this.button1.Text = "DataSorceの値を表示"; this.button1.Click += new System.EventHandler(this.button1_Click); // // button2 // this.button2.Location = new System.Drawing.Point(56, 200); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(136, 23); this.button2.TabIndex = 3; this.button2.Text = "DataSorceに値を設定"; this.button2.Click += new System.EventHandler(this.button2_Click); // // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(5, 12); this.ClientSize = new System.Drawing.Size(292, 266); this.Controls.Add(this.button2); this.Controls.Add(this.button1); this.Controls.Add(this.comboBox1); this.Controls.Add(this.textBox1); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); } #endregion /// <summary> /// アプリケーションのメイン エントリ ポイントです。 /// </summary> [STAThread] static void Main() { Application.Run(new Form1()); } private void button1_Click(object sender, System.EventArgs e) { MessageBox.Show( this.DataSorce.Hoge ); MessageBox.Show( this.DataSorce.Foo ); } private void button2_Click(object sender, System.EventArgs e) { this.DataSorce.Hoge = "変更しました。"; this.DataSorce.Foo = "03"; this.Refresh(); this.comboBox1.Refresh(); this.textBox1.Refresh(); // this.comboBox1.Visible = false; // this.comboBox1.Visible = true; // this.textBox1.Visible = false; // this.textBox1.Visible = true; } /// <summary> /// コンボボックスの要素を表すクラス /// </summary> public class ComboValueClass { /// <summary> /// ValueMember対応プロパティ名称 /// </summary> private static string valueMemberName = "Code"; public static string ValueMenberName { get{ return valueMemberName;} } /// <summary> /// DisplayMenber対応プロパティ名称 /// </summary> private static string displayMemberName = "Name"; public static string DisplayMenberName { get{ return displayMemberName;} } /// <summary> /// リストクラス保持配列 /// </summary> private static IList list = null; public static IList ComboList { get { if ( list == null ) { list = new ArrayList(); list.Add( new ComboValueClass( "01", "Test01" ) ); list.Add( new ComboValueClass( "02", "Test02" ) ); list.Add( new ComboValueClass( "03", "Test03" ) ); list.Add( new ComboValueClass( "04", "Test04" ) ); } return list; } } // コード private string code_; // 名称 private string name_; /// <summary> /// コンストラクタ /// </summary> public ComboValueClass( string code, string name ) { this.code_ = code; this.name_ = name; } /// <summary> /// コードの取得及び設定 /// </summary> public string Code { get{ return this.code_; } set{ this.name_ = value; } } /// <summary> /// 名称の取得及び設定 /// </summary> public string Name { get{ return this.name_; } set{ this.name_ = value; } } } /// <summary> /// ValueClass の概要の説明です。 /// </summary> public class ValueClass { private string hoge = "初期値"; private string foo = string.Empty; public ValueClass() { } public string Hoge { get { return hoge; } set { if (hoge != value) { hoge = value; OnHogeChanged(EventArgs.Empty); } } } public event EventHandler HogeChanged; protected virtual void OnHogeChanged(EventArgs e) { if (HogeChanged != null) HogeChanged(this, e); } public string Foo { get { return foo; } set { foo = value; } } } } } [ メッセージ編集済み 編集者: toppo 編集日時 2004-11-01 14:02 ] | ||||
|
投稿日時: 2004-11-01 14:36
南部です。
投稿日時: 2004-11-01 13:46 のコードで確かめてみましたが、 [DataSourceに値を設定]ボタンクリックで、 一番上のテキストボックスのテキストが 「変更しました。」 にすぐ更新されました。 #コピペしたんで、同一コード。 動作環境は、 Window 2000 Pro .NET Framework1.1 SP1 です。 #環境!? まじ? | ||||
|
投稿日時: 2004-11-01 15:04
toppoです。
すみません。 勘違いだったようです。 無事動作しました。 もう少し付き合ってもらいたいのですが、 私の脳みそではこの動作の説明がつきません。 ValueChangeのevent HogeChanged は いつnullじゃなくなるのでしょうか? だれも、valueClass.HogeChanged += xxxxx のような事をしている訳ではないのに。。。 protected virtual void OnHogeChanged(EventArgs e) { if (HogeChanged != null) { //※1 HogeChanged(this, e); } } の※1の箇所に処理がいかないと思っていました。 また、仮に何らかのしくみで、nullじゃ無くなり、処理が ※1に行ったとして、勝手に定義した、HogeChangedという イベントを誰がどのように処理しているのでしょうか? 文献でも良いので、教えていただけないでしょうか? | ||||
