【问题标题】:Is there a way to keep a DataGridView row selected when the user clicks on a cell in another row?当用户单击另一行中的单元格时,有没有办法保持选中 DataGridView 行?
【发布时间】:2011-06-23 04:44:26
【问题描述】:

DataGridView控件允许您单击行标题并选择行(整行突出显示),或使用鼠标单击并拖动选择多行等以选择所有行。

无论如何,如果用户决定单击DataGridView 中的某个单元格,我需要保持选中行。因此,如果用户单击所选行之一中的单元格,则所选行应保持突出显示。如果用户单击不同的、未选择行中的单元格,则所有当前选定的单元格都应保持突出显示。事实上,我不希望行选择改变 除非他们使用行标题。

这是很容易配置的东西,还是我需要几天的黑客攻击?

【问题讨论】:

  • 好吧,我想到了不同的方法来实现我想要的。大家不用再费心回答这个问题了!谢谢大家。
  • 最佳做法是发布您自己的解决方案并接受它 - 您将来可能会帮助某人。
  • 同时,您最好培训您的用户,让他们知道当他们点击一个单元格时,他们正在选择一行。他们应该很快学会这一点——这是默认行为。
  • 不,不是。您必须在 FullRowSelect 上使用它才能做到这一点。行标题上的小三角形并不意味着该行在选定行的集合中。默认情况下,我认为它设置为 RowHeaderSelect。无论如何,datagridview 的默认行为是完全 BS,我真的改变了很多
  • 反正我还没有解决这个问题...我只是改变了我的设计所以我不必解决它:(

标签: c# .net winforms datagridview


【解决方案1】:

不容易配置。花几天时间使用DataGridView 控件,您会注意到没有任何 易于配置,除非开发人员碰巧决定将其作为属性公开。而且只有最简单的东西才会以这种方式暴露出来,所以不要浪费太多时间去寻找。

当然,这可能的。我花了太多时间来继承 DataGridView 控件并覆盖让我觉得愚蠢的内置行为。但我真的不推荐给任何人。

更重要的是,您还应该认真重新考虑您是否甚至想要进行此特定更改。如果软件开始这样做,我将不知道发生了什么。我会立即怀疑我的 shift 键或鼠标按钮被卡住并尝试将它们敲开。下一步将是重新启动我的计算机。总的来说,不是一个非常积极的用户体验。这不是控件的行为方式是有原因的。请务必仔细考虑语义突出显示单元格的实际含义—通常,这意味着您可以一次更改所有选定单元格的值或删除所有选定单元格。如果这不是您的实现将如何工作,那么您可能一开始就不应该这样做。

【讨论】:

  • 为时已晚。我也对 datagridview 进行了子类化,并且已经修复了它的许多烦人的行为,并添加了一些对我有用的新行为。我已经想出了如何在其中添加自己的控件...我现在无法摆脱该死的 DGV。我越深入研究它的工作原理,似乎就越难找到有关它的帮助。嗯嗯。
  • @IsaacB:是的,那是因为 DGV 是一种没人愿意使用的混蛋控件。每个人做任何不平凡的事情最终都会重新实现该死的事情,但肯定不想花时间帮助其他人做同样的事情。痛苦的回忆,我想。如果您想完成此操作,您别无选择,只能将所有的选择行为掌握在自己手中。阻止控件将单元格、行或列添加到选定项属性,并在 OnRowHeaderMouseClick 方法的覆盖中自行添加。
  • "I've spent way too much of my life subclassing the DataGridView control"我听到了!
【解决方案2】:

我会说它不是一个好主意,从用户的角度来看,它和它不受欢迎的行为你需要告诉他们你的行只能通过行标题而不是通过点击它们来选择(相信我他们会感到沮丧)。在某种程度上,您完全避免了用户选择行。

也就是说,如果您热衷于进行此设计,那么您需要自己动手。 GridView 对此没有任何内置行为。您可以摆弄 RowChanged 事件和 CanSelect 属性并进行一些覆盖。

然后有一个RowHeaderMouseClick 事件可以用于从行标题中选择行。

【讨论】:

  • 不,这不是什么大问题。我的用户群最多为 4-5 人。他们已经习惯于单击行标题以删除多行。通过单击单元格选择行的事实现在在我的程序中没有任何意义。我不会因为摆脱它而放弃任何东西。
  • @IsaacB:啊,您是否将DataGridViewSelectionMode 属性设置为“FullRowSelect”?这将导致单击单个单元格以选择整行。如果这不是您想要的,请将该属性更改为“RowHeaderSelect”之类的内容。 (所有可能的值都列在here。)
  • @IsaacB 那么我已经提到了如何通过使用 RowHeaderMouseClick 事件来做到这一点......祝你好运:)
  • @Cody Gray RowHeaderSelect 模式仍然会在单击单元格时选择单元格。OP 仍然需要覆盖此行为
  • @Shekhar:不,它没有。单击其中一个单元格会选择该单元格,但它不会选择整行。目前尚不清楚这是否会真正解决问题中讨论的问题,但这可能是对他最后评论的回答。
【解决方案3】:

我设法绕过这个使用,呃... DataGridView 子类化,抱歉。

这可以干净地完成,在取消选择它们的内部机制之前和之后添加几个委托:

class SimpleDataGridView : DataGridView {

    public Action<DataGridViewCellMouseEventArgs> BeforeCellMouseDown;
    public Action<DataGridViewCellMouseEventArgs> AfterCellMouseDown;

    protected override void OnCellMouseDown(DataGridViewCellMouseEventArgs e) {
        if(BeforeCellMouseDown != null)
            BeforeCellMouseDown(e);

        base.OnCellMouseDown(e);

        if(AfterCellMouseDown != null)
            AfterCellMouseDown(e);
    }
}

然后,您可以在构造函数中以这种方式使用它。用您想要确定是否必须保留选择的方式替换“yourCondition”。

IEnumerable<DataGridViewRow> sel = null;

dataGridView1.BeforeCellMouseDown = 
    e => {
        if (yourCondition)
            sel = dataGridView1.SelectedRows.OfType<DataGridViewRow>();
        else
            sel = null;
    };

dataGridView1.AfterCellMouseDown = 
    e => {
        if(sel != null) {
            foreach(var row in sel)
                row.Selected = true;
        }
    };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多