Se si disattiva l'aggiornamento automatico di un'origine dati di binding impostando DataSourceUpdateMode = Never e quindi si utilizza un pulsante per aggiornare l'intero lotto (utilizzando binding.WriteValue), si verifica un problema - Vale a dire, solo il primo l'origine dati del controllo associato viene aggiornata. Tutti gli altri controlli vengono ripristinati sui valori originali.Associazione dati manuale utilizzando WriteValue
Questo perché quando l'oggetto corrente cambia (come accade dopo il precedente valore WriteValue), se ControlUpdateMode = OnPropertyChange, tutti gli altri controlli rileggeranno il valore dall'origine dati.
Qual è il metodo standard per evitare questo problema?
Un modo è quello di derivare una classe da BindingSource e aggiungere un metodo WriteAllValues. Questo metodo esegue le seguenti operazioni:
(1) Per ogni Binding, salvare il ControlUpdateMode
(2) Per ogni associazione, impostare ControlUpdateMode = Mai
(3) Per ogni Binding, chiamare il WriteValue metodo
(4) per ogni Binding, reimpostare ControlUpdateMode al valore memorizzato
(5) per ogni Binding, se ControlUpdateMode = onPropertyChange, chiamare il metodo ReadValue.
Riesci a vedere qualche problema con questo?
Se si lavora con le proprie classi, l'implementazione di IEditableObject risolve il problema?
In un altro controllo su cui sto lavorando, implemento il mio binding. Il modo in cui risolvo il problema è con il seguente codice. (Ho messo nel minimo indispensabile, spero che tu possa seguirla!):
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
Così, quando UpdateDataSourceFromControl viene chiamato, tutti gli eventi CurrentItemChanged saranno chiamati per tutti gli altri controlli nella stessa BindingSource. Tuttavia, poiché ControlDoingExplicitUpdate è impostato, non rileggeranno il valore dall'origine dati a meno che non si tratti del controllo che ha effettuato l'aggiornamento. ControlDoingExplicitUpdate è impostato su Nothing dopo che tutti questi eventi sono stati completati, in modo che il normale servizio riprenda.
Spero che tu possa seguire questo, e - di nuovo - chiedo, puoi vedere qualche problema con questo?