0

当用户更改我的“结束”日期 DateTinePicker 控件上的日期时,我有以下代码运行:

Private Sub dtpEndDate_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dtpEndDate.ValueChanged
    If dtpEndDate.Value.Date < dtpStartDate.Value.Date Then
        MessageBox.Show("The end date should be after the start date", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
        dtpEndDate.Value = Today
    End If
End Sub

这个过程似乎运行了两次,因为消息框显示了两次。

我有错误的事件,还是有更好的方法来管理这个?

我尝试按照建议使用变量对其进行编辑:

Private Sub dtpEndDate_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dtpEndDate.ValueChanged

If m_blndtpEndDateIsDone = False Then
    If dtpEndDate.Value.Date < dtpStartDate.Value.Date Then
        MessageBox.Show("The end date should be after the start date", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
        m_blndtpEndDateIsDone = True
        dtpEndDate.Value = Today
    Else
        m_blndtpEndDateIsDone = False
    End If
Else
    m_blndtpEndDateIsDone = False
End If
wnd sub

不幸的是,它仍然发射了两次......

我希望每次修改结束日期 dtpicker 并且日期在开始日期之前触发一次。

谢谢

菲利普

4

4 回答 4

3

MessageBox 可能会像这样很麻烦。它将焦点从控件上移开并泵出自己的消息循环。这可能会导致重入问题,使 DoEvents() 如此臭名昭著。DateTimePicker 控件不是为了很好地处理这个问题而编写的,它通常是一种笨拙的控件。

一个简单的解决方法是避免面对面的错误报告。ErrorProvider 组件可以很好地做到这一点。在你的表单上放一个,让你的代码看起来像这样:

Private Sub dtpEndDate_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dtpEndDate.ValueChanged
    If dtpEndDate.Value.Date < dtpStartDate.Value.Date Then
        ErrorProvider1.SetError(dtpEndDate, "The end date should be after the start date")
        dtpEndDate.Value = Today
    Else
        ErrorProvider1.SetError(dtpEndDate, "")
    End If
End Sub

实际上,您可以避免 MessageBox 创建的重入问题,您可以在 DateTimePicker 完成自己的事件处理之后通过稍后显示它来做到这一点。使用 Control.BeginInvoke() 在 Winforms 中优雅地完成。让它看起来像这样:

Private Sub dtpEndDate_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dtpEndDate.ValueChanged
    If dtpEndDate.Value.Date < dtpStartDate.Value.Date Then
        Me.BeginInvoke(New MethodInvoker(AddressOf reportDateProblem))
        dtpEndDate.Value = Today
    End If
End Sub

Private Sub reportDateProblem()
    MessageBox.Show("The end date should be after the start date", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
End Sub
于 2013-03-15T12:39:49.043 回答
1

这曾经发生在我身上。

您可以证明您至少在WebForms中的两个地方处理了一个事件:在 asp 页面中和在后面的代码中。如果我在后面代码中的“dtpEndDate_ValueChanged”方法的签名之后有语法“Handles dtpEndDate.ValueChanged”,那么我不必在我的aspx中写“OnClick =“dtpEndDate_ValueChanged”或类似的东西。

当您在WinForms而不是 WebForms 中时,请确保您没有

<< AddHandler dtpEndDate.ValueChanged, AddressOf Me.dtpEndDate_ValueChanged >>

或在 Load 方法或其他地方的某处类似的东西。

希望能帮助到你,

伊夫

于 2013-03-15T11:50:10.060 回答
1

您可以使用dtpEndDate_Validating事件

Private Sub dtpEndDate_Validating(sender As Object, e As CancelEventArgs)
    If dtpEndDate.Value.[Date] < dtpStartDate.Value.[Date] Then
        MessageBox.Show("The end date should be after the start date", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.[Error])
    End If
   e.Cancel = True
End Sub

或者

如果您想使用您的事件(dtpEndDate_ValueChanged),请在表单中定义一个布尔变量并将值设置为 false。在您执行第一次消息框后的事件中,将变量设置为 true。并检查这个变量

Dim isDone As Boolean = False

Private Sub dtpEndDate_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dtpEndDate.ValueChanged
If Not isDone Then
 If dtpEndDate.Value.Date < dtpStartDate.Value.Date Then
    MessageBox.Show("The end date should be after the start date", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
    IsDone = True
    dtpEndDate.Value = Today
 End If
End If

结束子

于 2013-03-15T11:52:28.660 回答
1

试试这个,

Private Sub dtpEndDate_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dtpEndDate.ValueChanged

     If (dtpEndDate.Value.Date < dtpStartDate.Value.Date) And Not dtpEndDate.Value = Today Then
            MessageBox.Show("The end date should be after the start date", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
            dtpEndDate.Value = Today
     End If

 End Sub

您将日期重置dtpEndDatetoday's date,因此您的日期dtpStartDate应该小于today,因此使用上述代码不会发生逻辑冲突。

于 2013-03-15T12:13:36.587 回答