2013-03-15 3 views
0

У меня есть ниже код, который выполняется, когда пользователь изменяет дату на моем контроле DateTinePicker «Ending» Дата:VB.NET 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 
     MessageBox.Show("The end date should be after the start date", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error) 
     dtpEndDate.Value = Today 
    End If 
End Sub 

Эта процедура, кажется, работает в два раза, в том, что MessageBox получает показано в два раза.

Есть ли у меня неправильное событие или есть лучший способ справиться с этим?

Я попытался редактирования с переменной, как предложено:

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 модифицирован и дата до даты начала.

благодаря

Филипп

+0

Почему dtpEndDate.Value = Сегодня? – andy

+0

ну, это было действительно отменить изменения ... –

+0

Это будет отображаться 'MessageBox' дважды, если' Today JosephHirn

ответ

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 

Вы на самом деле проблемы можно избежать повторного entrancy, что создает MessageBox, вы можете сделать это, показывая его позже, после того, как DateTimePicker завершил свою обработка собственных событий. Элегантно сделано в Winforms с помощью Control.BeginInvoke(). Сделайте так, чтобы это выглядело так:

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 
+0

Ну, во-первых, спасибо за то, что вы научили меня, хотя ваш первый метод не позволяет управлять показанием плохой даты, для пользователя нет сообщения о том, почему элемент управления не покажет выбранную дату - что мне не хватает? –

+1

Вы получаете значок ошибки, похожий на знак остановки дорожного движения. Наведите указатель мыши на него, чтобы получить сообщение об ошибке. Очень тонко. Если вы предпочитаете сообщение in-your-face, используйте второе предложенное мной решение. –

+0

Я также добавил событие dtpStartDate_ValueChanged, чтобы также очистить или показать ошибку, если пользователь решил неправильно установить стартовую кнопку StartDate! –

0

это случалось со мной.

Вы можете подтвердить, что вы обрабатываете событие в двух местах как минимум в WebForms: на странице asp и в коде. Если у меня есть синтаксис «Ручки dtpEndDate.ValueChanged» после сигнатуры метода «dtpEndDate_ValueChanged» в коде, указанном выше, тогда мне не нужно писать в моем aspx «OnClick =« dtpEndDate_ValueChanged »» или что-то в этом роде.

В то время как вы находитесь в WinForms, а не в WebForms, Убедитесь, что у вас нет

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

или что-то вроде что где-то в методе Load или в другом месте.

Надеется, что это помогает,

Ив

0

Либо вы можете использовать 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) затем определите булевскую переменную в форме an d установите для значения значение 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 

End Sub

+0

Я застрял, как сейчас, когда я использую событие _validating_, похоже, что он не срабатывает. Подпись - ** Private Sub dtpEndDate_Validating (ByVal отправитель как объект, ByVal e As System.ComponentModel.CancelEventArgs) обрабатывает dtpEndDate.Validating **, но он не срабатывает, хотя у меня есть точка останова. –

+0

Возможно ли, что I'v испортил код дизайнера? –

+0

Да, это правильно, но не то, что я хочу. Я предпочитаю попробовать и показать ему ошибку, когда сборщик данных для даты окончания до даты начала даты –

0

Попробуйте это,

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 

вы сбрасывая дату на dtpEndDate по today's date, так что ваши dtpStartDate должно быть меньше, чем today, так что будет не должно быть логического столкновения, используя вышеуказанный код.

+0

Я пробовал этот код, но он по-прежнему работает дважды, или показывает окно сообщения дважды - возможно, потому что я меняю значение на Сегодня? –

+0

@Philip вы можете показать даты, которые вы использовали в качестве входных данных? –

+0

спасибо за вашу помощь, но мне нравится решение ErroProvider, предложенное Гансом ниже! –

Смежные вопросы