views:

526

answers:

3

Say I've got a button on a form that I want to disable if some condition is met. Is there a way to check for this condition inside the button's "IsEnabled" event handler and modify the enabled state such that setting the enabled state a second time does not trigger another call to the IsEnabled event handler?

Let me demonstrate:

private void ExportResults_IsEnabledChanged (object sender, DependencyPropertyChangedEventArgs e)
{
 if (some condition)
 {
  uxExportResults.IsEnabled = false; // this will cause another call to the event handler, eventually resulting in a stack overflow
 }
}

Assume I'm triggering the event elsewhere (which I am).

+4  A: 
if (someCondition && uxExportResults.IsEnabled) { ... }

This will only disable your control if it's enabled.

Jon B
Jon, I just can't type fast enough, you're answer appeared as I was typing.
Steve Brouillard
+2  A: 

Simplest solution is to check the value of IsEnabled before you set it.

private void ExportResults_IsEnabledChanged (object sender, DependencyPropertyChangedEventArgs e)
{
  if (uxExportResults.IsEnabled == true)
  {
    uxExportResults.IsEnabled = false;
  }
}

Also, if you have the ability to change the code for the button, IsEnabled should not send the event unless the value actually changes.

public bool IsEnabled
{
  get { return isEnabled; }
  set
  {
    if(isEnabled != value)
    {
      isEnabled = value;
      IsEnabledChanged(this,args);
    }
  }
}
Will Eddins
+3  A: 

Another option is to temporarily disable the event like so:

private void ExportResults_IsEnabledChanged (object sender, DependencyPropertyChangedEventArgs e)
{
    if (some condition)
    {
        uxExportResults.IsEnabledChanged -= ExportResults_IsEnabledChanged;
        try
        {
            uxExportResults.IsEnabled = false; // this will cause another call to the event handler, eventually resulting in a stack overflow
        }
        finally
        {
            uxExportResults.IsEnabledChanged += ExportResults_IsEnabledChanged;
        }
    }
}
Paul Williams
hmmm, that sounded like a great idea, except it doesn't seem to disable the event handler.
scottmarlowe
You're right, it doesn't disable the event handler; it stops listening to that particular instance's events. If this handler were listening to events on multiple buttons, it would continue to receive those. Maybe you added the same event listener multiple times? I'd put a breakpoint on every line like "uxExportResults.IsEnabledChanged += " to see if they're called more than once.
Paul Williams