How can I temporarily disable events in a WPF solution?

65 Views Asked by At

I'm working on a C# WPF solution, based on XAML windows.
On one of those windows, I've added a DatePicker, and I want something to be done at two moments:

  • When the window is loaded
  • When the date in the DatePicker is changed.

This can be done very easily:

public void LoadData()
{
    date_DatePicker.SelectedDate = DateTime.Today;

    Do_Something();
}
private void DatePicker_DateChanged(object sender, SelectionChangedEventArgs e)
{
    if (date_DatePicker.SelectedDate.HasValue)
    {
        Do_Something();
    }
}

... but you see the problem: as the loading of the window caused a date, being filled in in the DatePicker, this launches the Do_Something(), causing this method to be launched twice.

I thought of disabling this, by checking e.OriginalSource, but apparently the date is already filled in there too (I was hoping (DatePicker)(e.OriginalSource).SelectedDate to be null).

Is there a way to say something like:

public void LoadData()
{
    disable_Events();
    date_DatePicker.SelectedDate = DateTime.Today;
    re-enable_Events();

    Do_Something();
}

or:

private void DatePicker_DateChanged(object sender, SelectionChangedEventArgs e)
{
    if ((date_DatePicker.SelectedDate.HasValue) && 
        !(previous_value_was_empty(sender,e)))  // <--- does such a thing exist?

Thanks in advance

3

There are 3 best solutions below

3
JonasH On

My typical approach is to use a flag:

if(!isDoingSomething){
    isDoingSomething = true;
    DoSomething();
    isDoingSomething = false;
}

You may want to use try/finally if there is a risk that DoSomething throws exceptions.

0
farzad On

you may try this

```cs
private bool isEventEnabled = true;

private void SomeEventHandler(object sender, EventArgs e)
{
       if (isEventEnabled)
{
    // the event handler logic 
}
}

// To temporarily disable events
private void DisableEvents()
{
   isEventEnabled = false;
}

// To re-enable 
private void EnableEvents()
{
    isEventEnabled = true;
}
0
Dominique On

I've found another answer to my question: as mentioned, the loading of the window fills in the DatePicker, and I want the Do_Something() when the window is loaded and when the DatePicker's value is modified, but not when it simply gets filled in while loading the window.

This can be done by checking on e.RemovedItems.Count: when the DatePicker gets filled in, this value is zero (as nothing is being removed), but while changing the DatePicker's value, the value of e.RemovedItems.Count becomes one, so my code becomes:

private void DatePicker_DateChanged(object sender, SelectionChangedEventArgs e)
{
    if ((date_DatePicker.SelectedDate.HasValue) && 
        (e.RemovedItems != null) && // I don't know if this even can be null
        (e.RemovedItems.Count != 0))
    {
        Do_Something();
        ...