MonthCalendar上的DateChanged事件出现问题

时间:2010-12-30 16:31:47

标签: c# winforms monthcalendar

尝试使用Google搜索,但无法真正找到答案。

使用具有MonthCalendar控件的Windows窗体并处理DateChanged事件。问题与鼠标点击的月份变化有关。

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

当在事件处理时调用MessageBox.Show(“任何东西”)时,事件处理程序似乎会被多次调用,并且日历会开始向后更改一个月。

有人知道为什么吗?

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

3 个答案:

答案 0 :(得分:3)

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

DateChanged事件将bool IsDateChanged设置为trueKeyUpMouseUp事件处理检查是否IsDateChanged并执行必要的代码+将IsDateChanged设置为false

答案 1 :(得分: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..
    }

答案 2 :(得分:0)

如果没有看到您的代码,很难确切地说出问题所在,但您可能正在调用一种方法来更改日期以响应鼠标点击。 Documentation for the DateChanged event说,

  

DateChanged事件发生在   任何日期选择,无论是鼠标,   键盘或代码。

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

仔细检查您的代码,看看您是否编写了一些内容,只要您单击鼠标就可以在控件中设置日期。如果您找不到它,请编辑您的问题并向我们展示您的代码,以便我们为您提供进一步的帮助。