How to disable button cell in WinForms DataGrid?

I have a WinForms application with a DataGridView control and a column of DataGridViewButtonCell cells. When I click on one of these buttons, it starts a background task, and I would like to disable the buttons until this task is completed.

I can disable the DataGridView control, but it does not provide visual information that the buttons are disabled. I want the user to see that the buttons are disabled, and note that the task completed when the buttons are turned on again.

Bonus points for a method that allows me to disable the buttons separately, so I can leave one of the buttons on during the execution of the task. (Please note that I cannot give out bonus points.)

+2
user-interface c # winforms
source share
2 answers

Here is the best solution I have found so far. This article in an MSDN article provides source code for a cell class that adds the Enabled property.

It works quite well, but there are two errors:

  • You must invalidate the grid after setting the Enabled property in any cells. It shows in the sample code, but I missed it.
  • Only a visual change that sets the Enabled property does not 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 spoil the look when the user clicked on it. Instead, I just turned off the entire grid. This works well for me, but I would prefer a method that allows me to disable some buttons without disconnecting the entire grid.

Here's a similar example in the DataGridView FAQ .

+3
source share

You can try:

When you click on a cell ...

  • Check if the process is started with the current row identifier from the list of classes; if so, exit the cell click event.
  • Save the line identifier in the list of running processes at the class level.
  • Change the button text to "Run ..." or something like that.
  • Attach a basic RunWorkerCompleted event handler to your process (explained briefly).
  • Call backgroundWorker.RunWorkerAsync (rowIdentifier).

In the DoWork event handler ...

  • Set e.Result = e.Argument (or create an object that will return both the argument and your desired result)

In the RunWorkerCompleted hanlder event ...

  • Remove the line identifier from the list of running processes (e.Result is the identifier).
  • Change the button text from "Run ..." to "Finish"
+1
source share

All Articles