トップ回答者
ユーザーコントロールのデータバインド可能なプロパティについて

質問
-
いつもお世話になっています。
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 PropertyPublic 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
回答
-
DBText の Setter で OnDBTextChanged を呼び出していませんが、それは大丈夫ですか?
また、***Changed パターンの場合、***Changed イベントは EventHandler 型でなければならなかったと思います。PropertyChangedEventHandler は、INotifyPropertyChanged インターフェイスを実装する際に使用されるイベント型です。
それから、データバインディングの DataSourceUpdateMode はデフォルトで OnValidation になっているはずです。このモードではそのコントロールが検証されるまで(一般的にはコントロールがフォーカスを失うときに検証されます)、データソースの値を変更しません。プロパティの値変更時に即時にデータソースを更新する場合は OnPropertyChanged に設定する必要があります。
コードからバインディングする場合は DataBindings.Add の引数で、デザイナからバインディングする場合はデータバインディングの(詳細)から指定したプロパティの「データソース更新モード」で設定します。- 回答としてマーク にゅう 2009年11月25日 5:05
-
大体正しいと思いますが、一点だけ。
OnDBTextChanged は、呼び出されるとデータソースに反映その他を行います。このとき、当然 DBText プロパティが参照されます。DBText の Setter の中でメンバ変数への保存以外にも処理を行っているようですが、それらの処理を行う前に他から DBText プロパティを参照されても大丈夫でしょうか?
それで問題ないのなら構いませんが、OnDBTextChanged の呼び出しは Setter の最後にした方が安全かも知れません。
// 個人的には Call キーワードは使わないけど、これはプロジェクトの方針とか個人の趣味とかの範疇でしょう。- 回答としてマーク にゅう 2009年11月25日 5:05
すべての返信
-
DBText の Setter で OnDBTextChanged を呼び出していませんが、それは大丈夫ですか?
また、***Changed パターンの場合、***Changed イベントは EventHandler 型でなければならなかったと思います。PropertyChangedEventHandler は、INotifyPropertyChanged インターフェイスを実装する際に使用されるイベント型です。
それから、データバインディングの DataSourceUpdateMode はデフォルトで OnValidation になっているはずです。このモードではそのコントロールが検証されるまで(一般的にはコントロールがフォーカスを失うときに検証されます)、データソースの値を変更しません。プロパティの値変更時に即時にデータソースを更新する場合は OnPropertyChanged に設定する必要があります。
コードからバインディングする場合は DataBindings.Add の引数で、デザイナからバインディングする場合はデータバインディングの(詳細)から指定したプロパティの「データソース更新モード」で設定します。- 回答としてマーク にゅう 2009年11月25日 5:05
-
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 PropertyPublic Event DBTextChanged As EventHandler
Public Sub OnDBTextChanged(ByVal e As EventArgs)
RaiseEvent DBTextChanged(Me, e)
End Sub
あと、デザイナからのバインディングで、「OnPropertyChanged」に更新モードも変更しています。
とりあえず、これで思いどおりの動きをしているように感じるのですが、自分では本当に正しいのか不安です・・・
(すいません、正式な検証は明日になると思います。)
なかなか、私にはハードルが高いことにチャレンジしている感はありますが、
がんばってみたいので、よろしくお願いします。 -
大体正しいと思いますが、一点だけ。
OnDBTextChanged は、呼び出されるとデータソースに反映その他を行います。このとき、当然 DBText プロパティが参照されます。DBText の Setter の中でメンバ変数への保存以外にも処理を行っているようですが、それらの処理を行う前に他から DBText プロパティを参照されても大丈夫でしょうか?
それで問題ないのなら構いませんが、OnDBTextChanged の呼び出しは Setter の最後にした方が安全かも知れません。
// 個人的には Call キーワードは使わないけど、これはプロジェクトの方針とか個人の趣味とかの範疇でしょう。- 回答としてマーク にゅう 2009年11月25日 5:05