在Windows窗体应用程序中捕获MonthCalendar控件的双击事件

6

如何捕获 System.Windows.Forms.MonthCalendar 控件的双击事件?我尝试使用 MouseDown 的 MouseEventArgs.Clicks 属性,但它始终为 1,即使我双击了。


你能解释一下你所指的日历控件是什么,以及你所针对的.NET Framework版本是哪个吗? - Nikola Malešević
本地的MonthCalendar没有双击事件。您想要实现什么? - UnhandledExcepSean
@Witchunter,抱歉,我的意思是System.Windows.Forms.MonthCalendar。 - Bogdan Verbenets
@SpectralGhost,我知道它没有双击事件,但这并不意味着我不能创建一个。我希望当用户在MonthCalendar上双击特定日期时弹出一个窗口。 - Bogdan Verbenets
3个回答

5
请注意,MonthCalendar在属性窗口中既不显示DoubleClick事件也不显示MouseDoubleClick事件。这个本地的Windows控件阻止这些事件的生成,这是一个明显的问题迹象。您可以通过观察MouseDown事件并测量点击之间的时间来合成自己的事件。
将下面的代码粘贴到项目中添加一个新类。编译后,从工具箱的顶部拖放新控件。为DoubleClickEx事件编写事件处理程序。
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;
}

你可以直接调用 base.OnDoubleClick(EventArgs.Empty)base.OnMouseDoubleClick(e); 并使用标准事件,而不是定义和调用自己的事件。 - Chaquotay
这并没有太大帮助,该事件在属性窗口和IntelliSense中都被隐藏了。 - Hans Passant
至少在我的环境中,标准的双击事件在 IntelliSense 中并没有被隐藏。但是对于属性窗口,你是正确的 :-( - Chaquotay
给编辑们:MyCalender()是一个构造函数而不是一个方法。请不要破坏代码。 - Hans Passant
如果您只想在日期位置上触发“DoubleClick”事件,而不是箭头符号或标题文本上触发,您可能需要检查HitTest()的结果,选择正确的HitArea进行双击检测,或者当Timedefault(DateTime)时忽略该事件。 - Chaquotay

4
你需要自己跟踪点击事件。你需要使用DateSelected事件来标记点击日期的时间,并使用DateChanged事件来“重置”时间跨度,以便不将点击不同日期视为双击。
请注意:如果使用鼠标按下事件,将会出现错误行为。
无论点击什么,鼠标按下事件都会发生,例如点击日历月份/年份等标题与点击真实日期一样。因此使用DateSelected而不是鼠标按下事件。
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));
}

0
最好添加以下代码,否则如果您快速点击两个日期,则会有事件发生。
    protected override void OnDateChanged(DateRangeEventArgs drevent) {
        lastClickTick = Environment.TickCount - 2 * SystemInformation.DoubleClickTime;
        base.OnDateChanged(drevent);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接