none
ユーザーコントロールのデータバインド可能なプロパティについて RRS feed

  • 質問

  • いつもお世話になっています。

    Pictureboxを継承したユーザーコントロールに、データベース(SQLServer2008EE)のデータとバインド可能な
    オリジナルのプロパティを持たせたいと思い、思考錯誤しております。

      Private _DBText As String

        <Description("データバインドされたテキスト")> _
        <System.ComponentModel.Bindable(True)> _
        Public Property DBText() As String
            Get
                Return _DBText
            End Get
            Set(ByVal value As String)
                _DBText = value
          
          (ここで別の処理をしています。)

            End Set
        End Property

        Public Event DBTextChanged As PropertyChangedEventHandler

        Public Sub OnDBTextChanged(ByVal e As System.ComponentModel.PropertyChangedEventArgs)
            RaiseEvent DBTextChanged(Me, e)
        End Sub


    上記コードにて、読み込み時の表示は上手くいったのですが、別のコントロールのコード上で、
    (継承コントロール名).DBText="文字列"
    としたところ、表示は上手くいくのですが、データセットにデータが反映されませんでした。

    何か他にもコードが必要なのでしょうか?
    よろしくお願いします。

    開発環境
     WindowsXP SP3 + VS2008StandardEdition(VB) + SQLServer2008ExpressEdtion

    2009年11月24日 10:41

回答

  • DBText の Setter で OnDBTextChanged を呼び出していませんが、それは大丈夫ですか?
    また、***Changed パターンの場合、***Changed イベントは EventHandler 型でなければならなかったと思います。PropertyChangedEventHandler は、INotifyPropertyChanged インターフェイスを実装する際に使用されるイベント型です。
    それから、データバインディングの DataSourceUpdateMode はデフォルトで OnValidation になっているはずです。このモードではそのコントロールが検証されるまで(一般的にはコントロールがフォーカスを失うときに検証されます)、データソースの値を変更しません。プロパティの値変更時に即時にデータソースを更新する場合は OnPropertyChanged に設定する必要があります。
    コードからバインディングする場合は DataBindings.Add の引数で、デザイナからバインディングする場合はデータバインディングの(詳細)から指定したプロパティの「データソース更新モード」で設定します。
    • 回答としてマーク にゅう 2009年11月25日 5:05
    2009年11月24日 12:28
  • 大体正しいと思いますが、一点だけ。
    OnDBTextChanged は、呼び出されるとデータソースに反映その他を行います。このとき、当然 DBText プロパティが参照されます。DBText の Setter の中でメンバ変数への保存以外にも処理を行っているようですが、それらの処理を行う前に他から DBText プロパティを参照されても大丈夫でしょうか?
    それで問題ないのなら構いませんが、OnDBTextChanged の呼び出しは Setter の最後にした方が安全かも知れません。

    // 個人的には Call キーワードは使わないけど、これはプロジェクトの方針とか個人の趣味とかの範疇でしょう。
    • 回答としてマーク にゅう 2009年11月25日 5:05
    2009年11月24日 15:35

すべての返信

  • DBText の Setter で OnDBTextChanged を呼び出していませんが、それは大丈夫ですか?
    また、***Changed パターンの場合、***Changed イベントは EventHandler 型でなければならなかったと思います。PropertyChangedEventHandler は、INotifyPropertyChanged インターフェイスを実装する際に使用されるイベント型です。
    それから、データバインディングの DataSourceUpdateMode はデフォルトで OnValidation になっているはずです。このモードではそのコントロールが検証されるまで(一般的にはコントロールがフォーカスを失うときに検証されます)、データソースの値を変更しません。プロパティの値変更時に即時にデータソースを更新する場合は OnPropertyChanged に設定する必要があります。
    コードからバインディングする場合は DataBindings.Add の引数で、デザイナからバインディングする場合はデータバインディングの(詳細)から指定したプロパティの「データソース更新モード」で設定します。
    • 回答としてマーク にゅう 2009年11月25日 5:05
    2009年11月24日 12:28
  • Hongliang様

     早速の返信ありがとうございます。

     ご意見を参考に下記のように変更してみました。
     
        <Description("データバインドされたテキスト")> _
        <System.ComponentModel.Bindable(True)> _
        Public Property DBText() As String
            Get
                Return _DBText
            End Get
            Set(ByVal value As String)
                _DBText = value
                Call OnDBTextChanged(EventArgs.Empty)  ←ここでいいのでしょうか?(あと呼び出し方も・・)
                (別の処理)
            End Set
        End Property

        Public Event DBTextChanged As EventHandler

        Public Sub OnDBTextChanged(ByVal e As EventArgs)
            RaiseEvent DBTextChanged(Me, e)
        End Sub

      あと、デザイナからのバインディングで、「OnPropertyChanged」に更新モードも変更しています。

      とりあえず、これで思いどおりの動きをしているように感じるのですが、自分では本当に正しいのか不安です・・・
      (すいません、正式な検証は明日になると思います。)

      なかなか、私にはハードルが高いことにチャレンジしている感はありますが、
      がんばってみたいので、よろしくお願いします。

    2009年11月24日 14:50
  • 大体正しいと思いますが、一点だけ。
    OnDBTextChanged は、呼び出されるとデータソースに反映その他を行います。このとき、当然 DBText プロパティが参照されます。DBText の Setter の中でメンバ変数への保存以外にも処理を行っているようですが、それらの処理を行う前に他から DBText プロパティを参照されても大丈夫でしょうか?
    それで問題ないのなら構いませんが、OnDBTextChanged の呼び出しは Setter の最後にした方が安全かも知れません。

    // 個人的には Call キーワードは使わないけど、これはプロジェクトの方針とか個人の趣味とかの範疇でしょう。
    • 回答としてマーク にゅう 2009年11月25日 5:05
    2009年11月24日 15:35
  • 返信おそくなりました。

    検証したところ、思いどおりの結果になりました。

    ですが、まだまだ内容までは全然理解したとは言えないレベルなので、
    またじっくりと勉強したいと思います。

    ありがとうございました。

    2009年11月25日 5:11