DataGridView (inherited) How to save a row internally

I have inherited the DataGridView (WinForms app) and created a custom control using it.  The DGV is bound to a BindingSource which uses an object List(of T) for its datasource.  The list has validation plumbing that is used to enable/disable an Accept button on the form if the elements are valid (so when the list is valid the accept button turns on and it off when it is valid or not).  This happens via the ListChanged event.

What I am attempting to accomplish is this behavior: If the List is valid (the Accept Button is enabled), pressing Enter in the DGV will override its normal behavior (move down one line) and instead fire the Accept button's click event.  This is accomplished via the following code:

    Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
        If keyData = System.Windows.Forms.Keys.Enter Then
            ' **** THIS IS WHERE A SUGGESTION IS NEEDED to accompllsh this:
            ' **** If the currentrow is dirty, apply the changes to the datasource

            Dim _ctl As System.Windows.Forms.Control = CType(Me.FindForm().AcceptButton, System.Windows.Forms.Control)
             If _Ctl IsNot Nothing and also _ctl.Enabled And _ctl.Visible Then
                CType(_ctl, System.Windows.Forms.IButtonControl).PerformClick()
                Return True
            End If
        End If
        Return MyBase.ProcessDialogKey(keyData)
    End Function

My problem is that pressing Enter on a row which is currently being edited is trapped by the above code BEFORE the changes are committed to the List so the state of the Accept button does not reflect whatever changes have been made to the row (whether modifications or a new row).  Therefore Accept may be enabled but the edits would cause it to not be enabled (and should not be Clicked) and vice versa.

Is there a way to determine inside the DGV that the current row is dirty and apply the changes at the point Enter is pressed (and trapped by the ProcessDialogKey override)?  Applying the changes to the List would fire the ListChanged event and change the state of the Accept button so the following test would be correct.

Thanks
GroupIII-GPhillipsAsked:
Who is Participating?
 
GroupIII-GPhillipsAuthor Commented:
Actually after more hours that I'd like to admit, I was able to come up with a solution that works.  The DataGridView has an EndEdit method that can be called internally.  The documentation was a little thin since it said it only worked on the current cell rather than the row, but it seems that by calling EndEdit on the cell when it is connected to an object it saves the value through the binding source to the actual object property.  That change to the property then threw the validate and changed events which accomplished what I needed.

The code inserted in my original is as follows:

            If MyBase.IsCurrentRowDirty Then
                MyBase.EndEdit()
            End If

Apparently as you exit each cell its value is committed through to the object or dataset that is the DGV's datasource.  I'm not sure how that relates to the Row header editing flag since it still shows a pencil.

samirbhogayta: Your suggestion was helpful, but I couldn't really apply it to my situation since it is not from a derived DataGridView.
0
 
SAMIR BHOGAYTAFreelancer and IT ConsultantCommented:
Hi, I had faced the same problem try this code for you

private string customerID;
private void customersDataGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
    if (!String.IsNullOrEmpty(customerID) && e.ListChangedType == ListChangedType.Reset)
    {
        int row = customersBindingSource.Find("Customer ID", customerID);
        customersDataGridView.BeginInvoke((MethodInvoker)delegate()
        {
            customersDataGridView.Rows[row].Selected = true;
            customersDataGridView.CurrentCell = customersDataGridView[0, row];
        });
    }
}
private void customersDataGridView_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.RowIndex == -1)
    {
        customerID = customersDataGridView.SelectedRows[0].Cells["customerIDColumn"].Value.ToString();
    }
}
0
 
GroupIII-GPhillipsAuthor Commented:
The only other comment did not address my specific question and did not apply to the derived instance of the DataGridView.  I was able to find a solution to the problem as specified.

If partial points are appropriate, then I could provide the responder with some points just because they tried.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.