Home > Back-end >  DataGridView 'OnRowValidating(DataGridViewCellCancelEventArgs e)' method is not calling fo
DataGridView 'OnRowValidating(DataGridViewCellCancelEventArgs e)' method is not calling fo

Time:03-18

I am trying to disable row selection in DataGridView in winforms. I used below code and its working as expected other than 1st row.

        protected override void OnRowValidating(DataGridViewCellCancelEventArgs e)
        {
            e.Cancel = true;
        }

For 1st row, this method is not calling and I am able to select the row. Can anyone have a solution for this issue

I would like to disable all kind of selections (Row, column or cell selection). I cannot use IsEnabled = false because horizontal/vertical scrolling need to be retained.

CodePudding user response:

I would like to disable all kind of selections (Row, column or cell selection). I cannot use Enabled = false because horizontal/vertical scrolling need to be retained.

To completely disable any selection in a DataGridView, you can set CurrentCell = null when a user changes Row or Cell, interacting with the Control.
This of course also disables any editing of the Cells.
It's like an enforced read-only mode; the default ReadOnly Property doesn't prevent a visible selection.

The grid can scroll and also clicking the Columns' headers allows to order the data.

Setting CurrentCell = null prevents all selections except when dragging the Mouse Pointer, which highlight Rows.
This happens only when MultiSelect = true, when set to false, no selection can be performed dragging the Mouse.

Suggested edit 1 (no selection allowed, no edit allowed, sorting allowed):

  • Added a SelectionEnabled public (modify as required) Property so you can toggle this state.
  • OnSelectionChanged is overridden to apply the state (you must call base before you set CurrentCell = null).

public class DataGridViewEx : DataGridView {

    private bool m_SelectionEnabled = true;
    private bool multiSelectCachedState = false;

    public DataGridViewEx() { }

    public bool SelectionEnabled { 
        get => m_SelectionEnabled;
        set {
            if (m_SelectionEnabled != value) {
                m_SelectionEnabled = value;
                if (!m_SelectionEnabled) {
                    multiSelectCachedState = MultiSelect;
                    MultiSelect = false;
                    ClearSelection();
                }
                else {
                    MultiSelect = multiSelectCachedState;
                }
            }
        } 
    }

    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);
        multiSelectCachedState = MultiSelect;
    }

    protected override void OnSelectionChanged(EventArgs e)
    {
        base.OnSelectionChanged(e);
        // Prevents Cell edit
        if (!m_SelectionEnabled) CurrentCell = null;
    }
}

Suggested edit 2 (no selection allowed, Cell edit allowed, sorting allowed):

As you can see in the .Net Source Code about CurrentCell, setting this property to null causes a call to ClearSelection(), but based on some conditions.

Calling ClearSelection() directly, causes a call to SetSelectedCellCore() (suspends bulk paint, clears the selection and invalidates Columns and Rows in the end), which doesn't prevent editing.

The code is, give or take, the same:

public bool SelectionEnabled { 
    get => m_SelectionEnabled;
    set {
        if (m_SelectionEnabled != value) {
            m_SelectionEnabled = value;
            if (!m_SelectionEnabled) ClearSelection();
        }
    } 
}

protected override void OnSelectionChanged(EventArgs e)
{
    base.OnSelectionChanged(e);
    // Does not prevent Cell edit
    if (!m_SelectionEnabled) ClearSelection();
}
  • Related