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


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.

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.

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.)


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

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.

There's a similar sample in the DataGridView FAQ.

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).

In the DoWork event handler...

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

In the RunWorkerCompleted event hanlder...

  1. Remove the row identifier from the running processes list (e.Result is the identifier).
  2. Change the button text from "Running..." to "Ready"

The short answer to your question is, "It doesn't." OpenID deliberately provides only a mechanism for having a centralized authentication site; it's up to you to decide which OpenID providers you personally consider acceptable. For example, Microsoft recently decided to allow OpenID on its Healthvault site only from a select few providers. A company may decide only to allow OpenID logins from its LDAP-backed access point, a government agency may only accept OpenIDs from biometrics-backed sites, and a blog might only accept TypePad due to their intense spam vetting.

There seems to be a lot of confusion over OpenID. Its original goal was simply to provide a standard login mechanism so that, when I need a secure login mechanism, I can select from any or all OpenID providers to handle that for me. Allowing anyone anywhere to set up their own trusted OpenID provider was never the goal. Doing the second effectively is impossible—after all, even with encryption, there's no reason you can't set up your own provider to securely lie and say it's authenticating whomever you want. Having a single, standardized login mechanism is itself already a great step forward.

This video can help you solving your question :)
By: admin