DataGridView - cell validation - prevent CurrentRow/Cell change

10,453

When I use mouse and click to another row, cell stays in edit mode, but another row gets selected.

Here I would use a global Boolean, bool isInvalidState say and a global DataGridViewCell = invalidCell object. In the default state you can set isInvalidState = false and invalidCell = null. Then using

private bool OnNotification(string cellValue)
{
    // Check for error.
    if (error)
        return false;
}

Then in the above method

void MyDataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == ColumnComment.Index) {
        object data = Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
        if((data != null) && (!CommentIsValid(data.ToString()))){
            CurrentCell = Rows[e.RowIndex].Cells[e.ColumnIndex];
            BeginEdit(true);

            // My notification method
            isInvalidState = OnNotification(
                String.Format("Comment `{0}` contains invalid characters));
            if (isInvalidState)
                invalidCell = MyDataGridView[e.RowIndex, e.ColumnIndex];
            return;
        }
    }
}

Now, wire-up an event CellContentClick on your DataGridView and check if isInvalidState == true

private void MyDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    if (isInvlaidState)
    {
        isInvalidState = false;
        MyDataGridView.CurrentCell = invalidCell;
        invalidCell = null;
        return;
    }
    // Do other stuff here.
}

When I try to use Enter (displays notification on invalid comment) and then Esc (to cancel edit) it uses value pushed by Enter (because edit mode has finished).

I am not sure about this problem; it is likely you will have to handle the KeyDown event and capture the escape key - handling it differently.

I hope this helps.

Share:
10,453
Vyktor
Author by

Vyktor

"I've been using VIM for 2 years now; mostly because I can't figure out how to turn it off." Started with html, php and C++. Now working with C, C#, python and doing some reverse engineering.

Updated on June 04, 2022

Comments

  • Vyktor
    Vyktor almost 2 years

    I have WinForms DataGridView with source set to SortableBindingList. In this form, there's column Comment and I need to prevent user from inserting some characters, thus validation.

    What I want to do is, whenever user enters invalid value, system will notify him (OnNotification( 'You entered wrong comment');) and force him/her to stay in edit mode.

    So far I build solution like this:

    void MyDataGridView_CellEndEdit( object sender, DataGridViewCellEventArgs e )
    {
        if (e.ColumnIndex == ColumnComment.Index) {
            object data = Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
            if( (data != null) && (!CommentIsValid( data.ToString()))){
                CurrentCell = Rows[e.RowIndex].Cells[e.ColumnIndex];
                BeginEdit( true );
    
                // My notification method
                OnNotification( String.Format( "Comment `{0}` contains invalid characters) );
                return;
            }
        }
    }
    

    I have following issues with this:

    • OnCellValidating is triggered only when whole form is closing or when current row is changed, not after I finish editing of single cell, so I've put check into CellEndEdit.
    • When I used Enter/Esc to end editing, it works as expected and desired.
    • When I use mouse and click to another row, cell stays in edit mode, but another row gets selected.
    • When I try to use Enter (displays notification on invalid comment) and then Esc (to cancel edit) it uses value pushed by Enter (because edit mode has finished).

    So my questions are:

    • How can I fire CellValidating after each cell edit, not when form is closing
    • How can I prevent CurrentRow and CurrentCell change even after mouse click?
    • How can I force cell to stay in edit mode?
  • Vyktor
    Vyktor about 11 years
    I mentioned in my question OnCellValidating is triggered only when whole form is closing or when current row is changed, not after I finish editing of single cell, so I've put check into CellEndEdit., so unsless you can suggest how to fire CellValidating before edit mode is closed, this would work. Otherwise it's useless :(
  • Umar T.
    Umar T. over 6 years
    Unfortunately, it didn't work for me fully as the code in CellContentClick event handler never set the control back to the cell being validated for its value. Nevertheless, your hint of using global variables 'isInvalidState' and 'invalidCell' helped me construct another solution that works perfectly fine. I'll try to post my solution here soon.