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?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.