Question

Tried googling, but cannot really find an answer.

Having a Windows Form with a MonthCalendar control and handling of the DateChanged event. the problem is related to change of month by mouse click.

I tried having a counter value shown in a label, which is counted up every time the event handler is called. When month is changed the event handler is called 2 times.

When MessageBox.Show("anything") is called at event handling, the event handler seems to get recalled several times and the calendar starts changing one month backward forever.

Do anybody know why?

Following code in the windows form class results in the described behaviour:

private void monthCalendar1_DateChanged(object sender, DateRangeEventArgs e)
{
    int i = int.Parse(labelDateChanged.Text);
    labelDateChanged.Text = (i + 1).ToString();
    MessageBox.Show(i.ToString());
}

private void monthCalendar1_DateSelected(object sender, DateRangeEventArgs e)
{
    int i = int.Parse(labelDateSelected.Text);
    labelDateSelected.Text = (i + 1).ToString();
}
Was it helpful?

Solution

Not catching ALL DateChanged events, but a solution is to handle DateChanged, KeyUp, and MouseUp events.

The DateChanged event sets a bool IsDateChanged to true. KeyUp and MouseUp event handling checks if IsDateChanged and executes the code necessary + sets IsDateChanged to false.

OTHER TIPS

Never use MessageBox in an event handler. Controls often get very confused when the focus is jerked away in one of their events. It keeps scrolling like this because it uses a timer to allow continuous scrolling when you lean on the next/prev button. Each timer tick scrolls the calendar again. That timer doesn't get disabled until the mouse button goes up. Which it cannot see, the message box got the mouse up message because it grabbed the focus. It is a bug in the native Windows control but this just never gets put to the test.

Using Debug.WriteLine() or a temporary Console.WriteLine() is helpful, output goes to the Output window and doesn't mess with the control events.

One way to get the event fired more than once is by accidentally subscribing the event more than once. In general you cannot assume how many events you'll get, there's a human clicking away at it. Be sure that your code is resilient to this.

A way to work around this behavior is to delay handling the event until after the event stopped running. Elegantly done with Control.BeginInvoke(). Like this:

    private void monthCalendar1_DateChanged(object sender, DateRangeEventArgs e) {
        this.BeginInvoke(new DateRangeEventHandler(delayedChanged), sender, e);
    }
    private void delayedChanged(object sender, DateRangeEventArgs e) {
        // etc..
    }

Without seeing your code, it's hard to say exactly what the problem is, but it's likely that you're calling a method to change the date in response to the mouse click. Documentation for the DateChanged event says,

The DateChanged event occurs during any date selection, whether by mouse, keyboard, or code.

So the DateChanged event will occur when you click the mouse to change the date. If your code that handles the mouse click also changes the date, then DateChanged will occur again.

Closely examine your code to see if you've written something that sets the date in the control whenever you click the mouse. If you can't find it, edit your question and show us your code so we can help you further.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top