none
カスタム プロパティの PropertyChanged イベントが効かない RRS feed

  • 全般的な情報交換

  • データ連結した DataGridView で一覧と詳細を表示するようなサンプルをよく
    見ます。

     

    - Windows フォームの 2 つの DataGridView コントロールを使用したマスター/詳細形式のフォームの作成
    - 新グリッド・コントロールの豊富な機能と高い表現力 - @IT


    詳細は、TextBox と BindingSource を以下のように接続しています。

     

    Code Snippet

     

    textBox1.DataBindings.Add("Text", columnBindingSource, "name", true);

     

     

     

    今回は、UserControl に TextBox を配置し、

    プロパティを介して BindingSource と接続させようと考えました。

     

    参考図 (1) データ テーブル

     

    参考図 (2) TextBox を内包した UserControl

     

    参考図 (3) 上に UserControl、下にデータ確認用 DataGridView


     

    UserControl に Time というプロパティを作り (参考コード(5)-(C))、
    参考コード (4)-(A) のように連結しました。


    参考コード (4) Form1

    Code Snippet

    public partial class Form1 : Form
    {
      ....

      private void Form1_Load(object sender, EventArgs e)
      {
        this.timeTableAdapter.Fill(this.timeDataSet.time);

     

        userControl11.DataBindings.Add("Time", this.timeBindingSource, "time", true);
      }                                                                     ........ (A)

     

      private void updateButton_Click(object sender, EventArgs e)
      {
        this.Validate();
        this.timeBindingSource.EndEdit(); .......................................... (B)
        this.tableAdapterManager.UpdateAll(this.timeDataSet);
      }
    }

     

     

    UserControl には、BindingSource.EndEdit() で PullData() されるようにと、
    INotifyPropertyChanged を実装しました。参照コード (5)-(D)。

     

    プロパティの変更は UserControl の内包 TextBox の TextChanged イベントで
    知らせるようにしました。参考コード (5)-(E)。

     

    参考コード (5) UserControl

    Code Snippet

    public partial class UserControl1 : UserControl, INotifyPropertyChanged
    {
      ....

      public string Time ........................................................... (C)
      {
        get { return DateTime.Now.ToShortTimeString(); }
        set { this.textBox1.Text = value; }
      }

     

      public event PropertyChangedEventHandler PropertyChanged;

     

      private void NotifyPropertyChanged(String propertyName) ...................... (D)
      {
        if (PropertyChanged != null)
        {
          PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
      }

     

      private void textBox1_TextChanged(object sender, EventArgs e) ................ (E)
      {
        this.NotifyPropertyChanged("Time");
      }
    }

     


    以上を準備し、

    1. 参考図 (3) に見える updateButton をクリックすると、
    2. 参考コード (4)-(B) の BindingSource.EndEdit() で PullData() が呼び出され、
    3. Time プロパティの getter が呼ばれ、
    4. Time プロパティの値が DataTable に渡されて
    5. 確認用 DataGridView に新しい時刻が表示される、

    と期待していたのですが、PullData() が実行されていないようなのです。

    参考コード (5)-(E) が実行されるものの、
    変更通知が伝わってないんじゃないかと予想しています。


     

    どうやれば、プロパティの変更が効くようになるのか、

    UserControl の Time プロパティ getter で PullData() によるデータ取得が行われるようになるのか、

    お分かりの方がいらっしゃったら、お教え願えませんか。

     

     

    同じことを UserControl の代わりに TextBox でやったら、

    Text プロパティの getter にアクセスがありました。

     

     

    参考

    - Re: INotifyPropertyChanged to notify sub-property change? - MSDN Forums

     

     


    + 追記 (2008-04-01)

     

    自己解決した、と思います。

     

    実際に組んでいたプログラムでは、プロパティを "Style" としていたので、
    UserControl 既存の "Style" プロパティとダブって、期待通りにならな
    かったのだと思います。名前を変えたら、期待通りでした。


     

    次に、サンプルとして提示している以下の件では、DataBindings.Add() の第4
    引数として DataSourceUpdateMode.OnPropertyChanged を指定すると、期待通り
    の動きとなりました。

     

    参考
    - Re: PropertyChangedEventHandler not firing automatically. - MSDN Forums

     

     

    後、PullData() は DataTable に既存データがないと敢えて呼ばれないように
    なっていたので、予め DataTable にデータを保存しておくと getter が呼ばれ
    ました。

    2008年3月31日 14:27

すべての返信

  • 想像1
     
    この文章は、別のスレッドへの返信をミスして新規に作成してしまったものである
     
    想像2
     
    この文章は、別のスレッドへの返信を前半にもち、後半で新しい質問をしている
     
    想像3
     
    この文章は、最初は中盤以降だけだったが、自己解決した旨を記事修正で冒頭に追加したものである
     
     
     
    上から順に思いつきました。他のことをしつつですが、1時間以上かけて。
    おそらく3番目があってるんだと思いますが、この投稿を見て簡単に判断できるようなものではありませんよね。
     
    質問をして解決すればOKというのではなく、後から情報源として見た人がわかりやすい内容にしておくのが、よりよい利用法だと思います。記事の修正そのものは悪いことでもないですし、私も後からこっそり書き換えることはよくやってますが、それはあくまで後から情報源としてみた人が、よりわかりやすいようにするためです。
     
    フォーラムがあって、スレッドがあって、そこに記事が連なっていくというのは、カテゴライズや話題の分化、そして時間軸の変化を伴っていることをわかりやすく表現しているので、このような場合には自分の投稿に自己解決したという旨の返信を記載するのが望ましいと思います。
     
    ・・・いや、想像3が正しければ、ですけどね。
     
    1・2・3どれがあってるにしても、後から見る人のことも考えて、今からでも前半の部分は削除し、その上でしかるべき投稿(別のスレッドに返信するなり、このスレッドへの返信にするなり)として書き直して欲しいと思います。
    2008年4月1日 5:02
  • 3 で合ってます。


    仰ること、その通りですね。時系列通りになっていません。


    書いている本人だから流れが分かることであり、その他の方々には推察させて
    しまいますね。修正しておきます。


    ご忠告ありがとうございます。

    2008年4月1日 6:04