capture doubleclick for MonthCalendar control in windows forms app
Asked Answered
B

3

6

How do I capture a doubleclick event of the System.Windows.Forms.MonthCalendar control? I've tried using MouseDown's MouseEventArgs.Clicks property, but it is always 1, even if I doubleclick.

Balmacaan answered 14/12, 2011 at 0:4 Comment(4)
Can you explain what are you referring to by Calendar control and which version of .NET Framework are you targeting?Gelignite
The native MonthCalendar doesn't have a double-click event. What are you trying to accomplish?Decern
@Witchunter, I'm sorry, I meant System.Windows.Forms.MonthCalendar.Balmacaan
@SpectralGhost, I know that it doesn't have a double-click event, but that doesn't mean that I can't create one. I want a window to popup when user doubleclicks on specific dates in MonthCalendar.Balmacaan
M
5

Do note that MonthCalendar neither shows the DoubleClick nor the MouseDoubleClick event in the Property window. Sure sign of trouble, the native Windows control prevents those events from getting generated. You can synthesize your own by watching the MouseDown events and measuring the time between clicks.

Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox. Write an event handler for the DoubleClickEx event.

using System;
using System.Windows.Forms;

class MyCalendar : MonthCalendar {
    public event EventHandler DoubleClickEx;

    public MyCalender() {
        lastClickTick = Environment.TickCount - SystemInformation.DoubleClickTime;
    }

    protected override void OnMouseDown(MouseEventArgs e) {
        int tick = Environment.TickCount;
        if (tick - lastClickTick <= SystemInformation.DoubleClickTime) {
            EventHandler handler = DoubleClickEx;
            if (handler != null) handler(this, EventArgs.Empty);
        }
        else {
            base.OnMouseDown(e);
            lastClickTick = tick;
        }
    }

    private int lastClickTick;
}
Matias answered 14/12, 2011 at 13:42 Comment(5)
Instead of defining and invoking your own event you can just call base.OnDoubleClick(EventArgs.Empty) and base.OnMouseDoubleClick(e); and use the standard events.Alcoholic
That doesn't help a great deal, the event is hidden both in the Properties window and in IntelliSense.Matias
At least in my environment the standard doubleclick events are not hidden in IntelliSense. But as for the Properties window you are right :-(Alcoholic
To editors: MyCalender() is a constructor, not a method. Don't break the code please.Matias
If you only want to trigger DoubleClick events on date locations and not on the arrow symbols or title texts you might want to check the result of HitTest(), either selecting the right HitArea for the double click detection or ignoring the event when Time is default(DateTime).Alcoholic
M
5

You'll need to keep track of the click events yourself. You need to use the DateSelected event to mark when a date is clicked, and the DateChanged event to 'reset' the time span so you don't count clicking different dates as a double click.

Note: if you use a mouse down event you will get buggy behavior

The mouse down event occurs no matter what is clicked, for example clicking on the month / year etc header of the Calendar will be registered just the same as clicking a real date. Hence the use of DateSelected instead of the mouse down event.

private DateTime last_mouse_down = DateTime.Now;

private void monthCalendar_main_DateSelected(object sender, DateRangeEventArgs e)
{
    if ((DateTime.Now - last_mouse_down).TotalMilliseconds <= SystemInformation.DoubleClickTime)
    {
        // respond to double click
    }
    last_mouse_down = DateTime.Now;
}

private void monthCalendar_main_DateChanged(object sender, DateRangeEventArgs e)
{
    last_mouse_down = DateTime.Now.Subtract(new TimeSpan(1, 0, 0));
}
Micronucleus answered 18/11, 2014 at 17:24 Comment(0)
C
0

Best to add following code, otherwise if you click quickly on two dates you will have the event.

    protected override void OnDateChanged(DateRangeEventArgs drevent) {
        lastClickTick = Environment.TickCount - 2 * SystemInformation.DoubleClickTime;
        base.OnDateChanged(drevent);
    }
Chanellechaney answered 19/3, 2014 at 13:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.