Wenn ich die automatische Aktualisierung einer Bindungsdatenquelle durch Setzen von DataSourceUpdateMode = Nie deaktivieren und dann eine Schaltfläche verwenden, um die gesamte Menge (mit binding.WriteValue) zu aktualisieren, tritt ein Problem - nämlich nur die erste Die Datenquelle des gebundenen Steuerelements wird aktualisiert. Alle anderen Steuerelemente werden auf die ursprünglichen Werte zurückgesetzt.Manuelle Datenbindung mit WriteValue
Dies ist, weil, wenn das aktuelle Objekt ändert (wie nach dem obigen WriteValue passiert), wenn ControlUpdateMode = OnPropertyChange, alle anderen Steuerelemente den Wert aus der Datenquelle neu lesen.
Was ist die Standardmethode zur Vermeidung dieses Problems?
Eine Möglichkeit besteht darin, eine Klasse von BindingSource abzuleiten und eine WriteAllValues-Methode hinzuzufügen. Diese Methode macht folgendes:
(1) für jede Bindungs, speichern Sie die ControlUpdateMode
(2) für jede Bindungs gesetzt ControlUpdateMode = Nie
(3) für jede Bindungs, rufen die Writevalue Verfahren
(4) für jede Bindungs, Reset ControlUpdateMode zu dem gespeicherten Wert
(5) für jede Bindungs, wenn ControlUpdateMode = OnPropertyChange, wobei das Verfahren Readvalue nennen.
Können Sie irgendwelche Probleme dabei sehen?
Wenn Sie mit Ihren eigenen Klassen arbeiten, würde die Implementierung von IEditableObject das Problem lösen?
In einem anderen Steuerelement, an dem ich arbeite, implementiere ich meine eigene Bindung. Die Art, wie ich das Problem dadurch umgehen kann, ist mit dem folgenden Code. (Ich habe in das Nötigste gesagt, ich hoffe es folgen!):
Private Shared ControlDoingExplicitUpdate As MyCustomControl = Nothing
Private Sub UpdateDataSourceFromControl(ByVal item As Object, ByVal propertyName As String, ByVal value As Object)
Dim p As PropertyDescriptor = Me.props(propertyName)
Try
ControlDoingExplicitUpdate = Me
p.SetValue(item, value)
Catch ex As Exception
Throw
Finally
ControlDoingExplicitUpdate = Nothing
End Try
End Sub
Private Sub DataBindingSource_CurrentItemChanged(ByVal sender As Object, ByVal e As System.EventArgs)
If (ControlDoingExplicitUpdate IsNot Nothing) AndAlso (ControlDoingExplicitUpdate IsNot Me) Then Exit Sub
Me.UpdateControlFromDataSource() 'Uses ReadValue
End Sub
Also, wenn UpdateDataSourceFromControl genannt wird, werden alle CurrentItemChanged Ereignisse werden für alle anderen Kontrollen im gleichen Binding aufgerufen werden. Da ControlDoingExplicitUpdate jedoch festgelegt ist, werden sie den Wert aus der Datenquelle nicht erneut einlesen, es sei denn, sie sind das Steuerelement, das die Aktualisierung durchgeführt hat. ControlDoingExplicitUpdate wird auf Nothing gesetzt, nachdem alle diese Ereignisse abgeschlossen wurden, sodass der normale Dienst wieder aufgenommen wird.
Ich hoffe, Sie können dies folgen, und - wieder - ich frage, können Sie irgendwelche Probleme mit diesem sehen?