Link to home
Start Free TrialLog in
Avatar of GroupIII-GPhillips
GroupIII-GPhillipsFlag for United States of America

asked on

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
Avatar of SAMIR BHOGAYTA
SAMIR BHOGAYTA
Flag of India image

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();
    }
}
ASKER CERTIFIED SOLUTION
Avatar of GroupIII-GPhillips
GroupIII-GPhillips
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of GroupIII-GPhillips

ASKER

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.