I have a DataGridView bind to a BindingSource in the windows form, when the current row of the DataGridView is changed, the CurrentChanged event of BindingSource is fired.
i want to validate current row before it changed to cancel changing current row. the CurrentChanged event is fired after that.
is there a solution to solve the problem?
i had the same problem. It would be really great to have an Event like "CurrentChanging" in the BindingSource component. Unfortunately it seems not to be too important for Microsoft, to implement that event.
Microsoft: Consider this:
When the user made changes to the current record/object and moves to the next record the current record/object is stored on the database. The record/object is validated on the database side. Only if the validation was sucessful the user is moved to the next record.
In the meantime i thought about the following solution
- Override BindingSource
- Add a new Event CurrentChanging(seender as Object, e as CanceelEventArgs)
- Override the Procedure OnCurrentChanged (which raises the event CurrentChanged)
- Move immediatly back to the unvalidated record
- Call the new event CurrentChanging
- If e.cancel = false move to the record which was desired before
And here is the code:
Public Class BindingSourceX
#Region " Constructors "
'BindingSourceX should have the same constructors as BindingSource
Public Sub New()
Public Sub New(ByVal container As System.ComponentModel.IContainer)
Public Sub New(ByVal dataSource As Object, ByVal dataMember As String)
#Region " Private Fields "
Private _Move As Boolean = False
Private _StoredPosition As Integer = -1
Private _StoredCurrent As Object = Nothing
#Region " CurrentChanging Event "
Public Event CurrentChanging(ByVal Sender As Object, ByVal e As CancelEventArgs)
Protected Overridable Sub OnCurrentChanging(ByVal e As System.ComponentModel.CancelEventArgs)
RaiseEvent CurrentChanging(Me, e)
Protected Overrides Sub OnPositionChanged(ByVal e As System.EventArgs)
'Overriding OnPositionChanged without calling the underlying base procedure
'prevents from uncontrolled executions of PositionChanged Event
'With other words: MyBase.OnPositionChanged is called by OnCurrentCahanged only.
Protected Overrides Sub OnCurrentChanged(ByVal e As System.EventArgs)
If _Move _
OrElse _StoredCurrent Is Nothing _
OrElse _StoredPosition > (Me.Count - 1) Then
'Move to the desired record (by calling the base procedure) if one of the following conditions is true:
'- _Move is set to true
'- _StoredCurrent is nothing (No current record and user adds a new row)
'- _StoredPosition > (Count - 1) (User has deleted the last record)
'Position has changed, too
'Store new values
_StoredCurrent = Me.Current
_StoredPosition = Me.Position
ElseIf _StoredPosition = Me.Position AndAlso Not _StoredCurrent.Equals(Me.Current) Then
'Move to the desired record (by calling the base procedure)
'if one of the following conditions is true:
'- _StoredPosition = aspirated position but _StoredCurrent <> aspirated object (user has deleted a record in the middle)
'Position has not changed this time
'Store new values
_StoredCurrent = Me.Current
ElseIf _StoredPosition <> Me.Position Then
'Store the desired position
Dim p As Integer = Me.Position
'Move immediately back to previously stored position
Me.Position = _StoredPosition
'Raise CurrentChanging Event
Dim ce As New CancelEventArgs
'Move to the aspirated position if the move was not canceled
If Not ce.Cancel Then
_Move = True
Me.Position = p
_Move = False
'Nothing happens when immediatly moving back to the stored position
This post was made two years ago... Um, is there a work around for this yet? I want to do some validation when the user tries to move off the current record and need to cancel the move if the validation isn't met...or have we been working on better things like wpf?
After another four and a half years we have yet to see CurrentChanging in BindingSource. Say what if I'm not using DataGridView and working with plain simple control binding; I don't get any ROW-LEVEL Validating event where I could stop the CurrencyManager from moving to the new record.
A relatively simple solution seems to work for what I need to do but it might not work for delayed validation as requested in the question. I need to process the previous value because I have a WebBrowser control and it does not provide notification of changes. In CurrentChanged I store the contents of the WebBrowser control into the previous record.
I have a "previous" variable (that is initially null) that is the same type as the BindingSource.Current. In CurrentChanged if "previous" is not null then I process it as the previous value. Then I set "previous" to BindingSource.Current.