【问题标题】:Problem with DateChanged event on MonthCalendarMonthCalendar 上的 DateChanged 事件的问题
【发布时间】:2010-12-30 16:31:46
【问题描述】:

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

拥有一个带有 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();
}

【问题讨论】:

    标签: c# winforms monthcalendar


    【解决方案1】:

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

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

    【讨论】:

      【解决方案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..
          }
      

      【讨论】:

      • 我有一些繁重的代码在我的原始代码中做了很多事情。我可以通过调用 MessageBox.Show() 重新创建问题。我怎样才能在 MonthCalendar 控件的 datechange 上触发“做很多事情”?
      • 再想一想,不太确定这是否会解决它,但它仍然会转移焦点。不确定,这个错误在 Vista 中已修复,我无法测试。
      • 你不确定它是否在 Vista 中工作,我现在可以肯定地说它不能 :-( 尚未在 Windows 7 上测试。
      • @HansPassant :我遇到了一个问题,消息框在事件处理程序中获得焦点,导致奇怪的行为。用你的解决方法解决了。非常感谢..
      【解决方案3】:

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

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

      所以DateChanged 事件会在您单击鼠标更改日期时发生。如果您处理鼠标点击的代码也更改了日期,那么DateChanged 将再次出现。

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

      【讨论】:

      • 我从一个简单的表单中添加了代码来隔离问题。日期没有改变。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多