ComboBox
デフォルトの , TextBox
(フォーカスを受け取るためだけに) と.を追加した空白のフォームがありますLabel
。コンボボックスには、フォームのプライベート プロパティに設定されたデータ バインディングがあります。
設定:
Private Sub FormLoad(sender As System.Object, e As System.EventArgs) _
Handles MyBase.Load
Dim data = {New With {.Display = "", .Value = ""},
New With {.Display = "A", .Value = "A"},
New With {.Display = "B", .Value = "B"},
New With {.Display = "C", .Value = "C"}}
ComboBox1.DataSource = data
ComboBox1.DisplayMember = "Display"
ComboBox1.ValueMember = "Value"
ComboBox1.DataBindings.Add("SelectedValue", someClass, "SomeProperty")
End Sub
someClass は、SomeClass
以下のタイプのプライベート変数です。
Public Class SomeClass
Private _someProperty As String = ""
Public Property SomeProperty() As String
Get
Return _someProperty
End Get
Set(ByVal value As String)
_someProperty = value
Form1.Label1.Text = String.Format("Some property = ""{0}""", value)
End Set
End Property
End Class
予想される行動:
デフォルトBinding.DataSourceUpdateMode
では、変更が伝播されOnValidation
ます。
から値を選択してComboBox
をクリックするとTextBox
、DataBinding は指定されたプロパティに新しい値を書き込み、メイン フォームのラベルが更新されます。
考えられるバグ:
問題が発生するのは、選択が行われるとすぐに検証を実行する必要があるビジネス ルールがあるためです。検証を開始するには、ComboBox がフォーカスを失う必要があるため、次のコードをSelectionChangeCommitted
イベントに追加することで、プログラムで検証を強制できます。
Private Sub ComboChanged(sender As System.Object, e As EventArgs) _
Handles ComboBox1.SelectionChangeCommitted
TextBox1.Focus()
End Sub
問題は、これが最初の選択のデータバインディングを壊すことです。コンボボックスは間違いなくフォーカスを失い、間違いなく new がSelectedValue
あり、検証が確実に開始されましたが、データバインディングは新しい値をSomeProperty
on に書き込みませんでしたsomeClass
(セッターは決して開始せず、この例ではラベルは更新されません)。後続の選択では、セッターが起動します
必要に応じて、ComboBox1.SelectionChangeCommitted
イベントから手動でデータバインディングを記述しますが、検証イベント中にもコードを処理する必要があるため、これは余分な作業のように感じます。
ComboBox1.DataBindings.Item("SelectedValue").WriteValue()
質問:
- プログラムと手動でフォーカスを失うことは同じことをするべきではありませんか?
- これが後続の選択では機能するのに、最初の選択では機能しないのはなぜですか?
- これは実際には WinForms のバグですか、それとも何かひどく間違ったことをしたのでしょうか?
アップデート:
これまでの回答に感謝します。回避策よりも説明を探していたと思います。コントロールが検証されても、検証時に更新されるバインドされたプロパティが更新されないのはなぜでしょうか。さらに、なぜそれが初めてではなく、将来のすべてのイベントで機能するのでしょうか?