C# MonthCalendar上的DateChanged事件出现问题

C# MonthCalendar上的DateChanged事件出现问题,c#,winforms,monthcalendar,C#,Winforms,Monthcalendar,尝试过谷歌搜索,但无法真正找到答案 具有带有MonthCalendar控件的Windows窗体,并处理DateChanged事件。这个问题与鼠标点击改变月份有关 我尝试在标签中显示一个计数器值,每次调用事件处理程序时都会对其进行计数。当月份更改时,事件处理程序被调用2次 当在事件处理中调用MessageBox.Show(“任何东西”)时,事件处理程序似乎会被调用多次,日历将开始向后更改一个月 有人知道为什么吗 windows窗体类中的以下代码导致所描述的行为: private void mont

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

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

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

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

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


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

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

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

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


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

切勿在事件处理程序中使用MessageBox。当焦点在控件的某个事件中突然偏离时,控件通常会变得非常混乱。它一直像这样滚动,因为它使用一个计时器,当你靠在下一个/上一个按钮上时,可以连续滚动。每个计时器滴答声都会再次滚动日历。直到鼠标按钮启动,计时器才会被禁用。它看不到,消息框得到了鼠标向上的消息,因为它抓住了焦点。这是本机Windows控件中的一个bug,但它从未被测试过

使用Debug.WriteLine()或临时控制台.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..
    }

不要在事件处理程序中使用MessageBox。当焦点在控件的某个事件中突然偏离时,控件通常会变得非常混乱。它一直像这样滚动,因为它使用一个计时器,当你靠在下一个/上一个按钮上时,可以连续滚动。每个计时器滴答声都会再次滚动日历。直到鼠标按钮启动,计时器才会被禁用。它看不到,消息框得到了鼠标向上的消息,因为它抓住了焦点。这是本机Windows控件中的一个bug,但它从未被测试过

使用Debug.WriteLine()或临时控制台.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..
    }

无法捕获所有
DateChanged
事件,但解决方案是处理
DateChanged
KeyUp
MouseUp
事件


DateChanged
事件将bool
IsDateChanged
设置为
true
KeyUp
MouseUp
事件处理检查
IsDateChanged
并执行必要的代码+将
IsDateChanged
设置为
false
不捕获所有
DateChanged
事件,但解决方案是处理
DateChanged
KeyUp>,和
MouseUp
事件


DateChanged
事件将bool
IsDateChanged
设置为
true
KeyUp
MouseUp
事件处理检查
IsDateChanged
并执行必要的代码+将
IsDateChanged
设置为
false

我添加了用于隔离问题的简单表单中的代码。日期没有改变。我添加了一个简单表单中的代码来隔离问题。日期没有改变。我有一些繁重的代码在我的原始代码中做了很多事情。只要调用MessageBox.Show(),我就可以重现这个问题。我怎样才能在MonthCalendar控件上的datechange上触发“做很多事情”呢?再想一想,不太确定这是否会解决它,它仍然会将焦点拉走。不确定,这个错误是在Vista中修复的,我无法测试它。你不确定它是否在Vista中工作,我现在可以肯定地说它不工作:-(尚未在Windows 7上测试过)。@HansPassant:我面临