DataGridView 'OnRowValidating(DataGridViewCellCancelEventArgs e)' 方法未调用第一行

DataGridView 'OnRowValidating(DataGridViewCellCancelEventArgs e)' method is not calling for the 1st row

我试图在 winforms 的 DataGridView 中禁用行 selection。我使用了下面的代码,除了第一行之外,它的工作正常。

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

对于第一行,此方法未调用,我可以 select 该行。 谁能解决这个问题

我想禁用所有类型的 selection(行、列或单元格 selection)。 我不能使用 IsEnabled = false 因为 horizontal/vertical 滚动需要保留。

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.

要完全禁用 DataGridView 中的任何选择,您可以设置 CurrentCell = null 当用户更改行或单元格时,与控件交互。
这当然也会禁用对单元格的任何编辑。
这就像一个 enforced read-only 模式;默认 ReadOnly 属性 不会阻止可见选择。

网格可以滚动,也可以单击列的 headers 允许对数据进行排序。

设置 CurrentCell = null 阻止所有选择,拖动鼠标指针时除外,这会突出显示行。
仅当MultiSelect = true时出现此情况,当设置为false时,拖动鼠标无法执行选择。

建议编辑 1(不允许选择,不允许编辑,允许排序):

  • 添加了 SelectionEnabled public(根据需要修改)属性 以便您可以切换此状态。
  • OnSelectionChanged 被覆盖以应用状态(您必须在设置 CurrentCell = null 之前调用 base)。

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;
    }
}

建议编辑 2(不允许选择,允许单元格编辑,允许排序):

如您在 .Net Source Code about CurrentCell 中所见,将此 属性 设置为 null 会导致调用 ClearSelection(),但基于某些条件。

直接调用 ClearSelection(),导致调用 SetSelectedCellCore()(暂停批量绘制,清除选择并最终使列和行无效),这不会阻止编辑。

代码是,给还是拿,一样的:

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();
}