1

尝试谷歌搜索,但无法真正找到答案。

拥有一个带有 MonthCalendar 控件和处理 DateChanged 事件的 Windows 窗体。该问题与通过鼠标单击更改月份有关。

我尝试在标签中显示一个计数器值,每次调用事件处理程序时都会对其进行计数。当月份更改时,事件处理程序被调用 2 次。

当在事件处理中调用 MessageBox.Show("anything") 时,事件处理程序似乎被调用了几次,并且日历开始永远向后更改一个月。

有人知道为什么吗?

windows窗体类中的以下代码会导致所描述的行为:

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();
}
4

3 回答 3

3

不捕获所有DateChanged事件,但解决方案是处理DateChangedKeyUpMouseUp事件。

DateChanged事件将 bool 设置IsDateChangedtrueKeyUpMouseUp事件处理检查是否IsDateChanged并执行必要的代码 + 设置IsDateChangedfalse.

于 2011-01-11T14:11:26.283 回答
2

永远不要在事件处理程序中使用 MessageBox。当焦点在其中一个事件中被猛拉时,控件通常会变得非常混乱。它一直像这样滚动,因为当您靠在下一个/上一个按钮时,它使用计时器来允许连续滚动。每个计时器滴答声都会再次滚动日历。在鼠标按钮上升之前,该计时器不会被禁用。它看不到,消息框得到了鼠标向上消息,因为它抓住了焦点。这是本机 Windows 控件中的一个错误,但这永远不会经过测试。

使用 Debug.WriteLine() 或临时 Console.WriteLine() 很有帮助,输出会转到“输出”窗口并且不会与控制事件混淆。

多次触发事件的一种方法是多次意外订阅事件。一般来说,你不能假设你会得到多少事件,有一个人点击它。确保您的代码对此具有弹性。

解决此问题的一种方法是将事件处理延迟到事件停止运行之后。使用 Control.BeginInvoke() 优雅地完成。像这样:

    private void monthCalendar1_DateChanged(object sender, DateRangeEventArgs e) {
        this.BeginInvoke(new DateRangeEventHandler(delayedChanged), sender, e);
    }
    private void delayedChanged(object sender, DateRangeEventArgs e) {
        // etc..
    }
于 2010-12-30T17:46:46.937 回答
0

如果没有看到您的代码,很难确切地说出问题出在哪里,但很可能您正在调用一个方法来更改日期以响应鼠标单击。DateChanged 事件的文档说,

DateChanged 事件在任何日期选择期间发生,无论是通过鼠标、键盘还是代码。

因此,DateChanged当您单击鼠标更改日期时,将发生该事件。如果您处理鼠标单击的代码也更改了日期,则将DateChanged再次发生。

仔细检查你的代码,看看你是否写了一些东西来在你点击鼠标时在控件中设置日期。如果找不到,请编辑您的问题并向我们展示您的代码,以便我们进一步帮助您。

于 2010-12-30T17:45:57.643 回答