C# 如何禁用 WinForms DataGrid 中的按钮单元格?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/86096/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 11:26:16  来源:igfitidea点击:

How do I disable a button cell in a WinForms DataGrid?

提问by Don Kirkby

I have a WinForms application with a DataGridView control and a column of DataGridViewButtonCell cells within that. When I click on one of these buttons, it starts a background task, and I'd like to disable the buttons until that task completes.

我有一个 WinForms 应用程序,其中包含一个 DataGridView 控件和一列 DataGridViewButtonCell 单元格。当我单击这些按钮之一时,它会启动一个后台任务,我想禁用这些按钮,直到该任务完成。

I can disable the DataGridView control, but it gives no visual indication that the buttons are disabled. I want the user to see that the buttons are disabled, and to notice that the task has finished when the buttons are enabled again.

我可以禁用 DataGridView 控件,但它没有给出按钮被禁用的视觉指示。我希望用户看到按钮被禁用,并注意到当按钮再次启用时任务已经完成。

Bonus points for a method that allows me to disable the buttons individually, so I can leave one of the buttons enabled while the task runs. (Note that I can't actually give out bonus points.)

允许我单独禁用按钮的方法的奖励积分,因此我可以在任务运行时启用其中一个按钮。(请注意,我实际上无法发放奖励积分。)

采纳答案by Don Kirkby

Here's the best solution I've found so far. This MSDN articlegives the source code for a cell class that adds an Enabled property.

这是我迄今为止找到的最佳解决方案。此MSDN 文章提供了添加 Enabled 属性的单元格类的源代码。

It works reasonably well, but there are two gotchas:

它工作得相当好,但有两个问题:

  1. You have to invalidate the grid after setting the Enabled property on any cells. It shows that in the sample code, but I missed it.
  2. It's only a visual change, setting the Enabled property doesn't actually enable or disable the button. The user can still click on it. I could check the enabled property before executing the click event, but it also seemed to be messing up the appearance when the user clicked on it. Instead, I just disabled the entire grid. That works alright for me, but I'd prefer a method that allows me to disable some buttons without disabling the entire grid.
  1. 在任何单元格上设置 Enabled 属性后,您必须使网格无效。它在示例代码中显示了这一点,但我错过了。
  2. 这只是一个视觉变化,设置 Enabled 属性实际上并没有启用或禁用按钮。用户仍然可以点击它。我可以在执行 click 事件之前检查 enabled 属性,但是当用户单击它时,它似乎也弄乱了外观。相反,我只是禁用了整个网格。这对我来说没问题,但我更喜欢一种方法,它允许我禁用某些按钮而不禁用整个网格。

There's a similar sample in the DataGridView FAQ.

DataGridView FAQ 中有一个类似的示例。

回答by Austin Salonen

You could give this a try:

你可以试试这个:

When you click on the cell...

当你点击单元格...

  1. Check to see if the process with the current row identifier is running from a class-level list; if so, exit the cell click event.
  2. Store the row identifier in the class-level list of running processes.
  3. Change the button text to "Running..." or something appropriate.
  4. Attach a basic RunWorkerCompleted event handler to your process (explained shortly).
  5. Call backgroundWorker.RunWorkerAsync(rowIdentifier).
  1. 检查具有当前行标识符的进程是否正在从类级列表运行;如果是这样,退出单元格单击事件。
  2. 将行标识符存储在正在运行的进程的类级列表中。
  3. 将按钮文本更改为“正在运行...”或其他适当的内容。
  4. 将基本的 RunWorkerCompleted 事件处理程序附加到您的进程(稍后解释)。
  5. 调用 backgroundWorker.RunWorkerAsync(rowIdentifier)。

In the DoWork event handler...

在 DoWork 事件处理程序中...

  1. Set e.Result = e.Argument (or create an object that will return both the argument and your desired result)
  1. 设置 e.Result = e.Argument(或创建一个将返回参数和您想要的结果的对象)

In the RunWorkerCompleted event hanlder...

在 RunWorkerCompleted 事件处理程序中...

  1. Remove the row identifier from the running processes list (e.Result is the identifier).
  2. Change the button text from "Running..." to "Ready"
  1. 从正在运行的进程列表中删除行标识符(e.Result 是标识符)。
  2. 将按钮文本从“正在运行...”更改为“就绪”