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

メッセージボックスが 2 回表示されるという点で、この手順は 2 回実行されているようです。

私は間違ったイベントを持っていますか、またはこれを管理するためのより良い方法はありますか?

提案されているように変数で編集してみました:

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

残念ながら、まだ2回発射されています...

終了日 dtpicker が変更され、日付が開始日より前になるたびに1回起動するようにします。

ありがとう

フィリップ

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

これを試してみてください、

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 datedtpStartDateより小さくする必要がありますtoday。したがって、上記のコードを使用しても論理的な衝突は発生しません。

于 2013-03-15T12:13:36.587 に答える
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

また

event(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

これは私によく起こりました。

少なくともWebFormsの 2 つの場所(asp ページとコード ビハインド) でイベントを処理することを証明できます。上記のコード ビハインドの「dtpEndDate_ValueChanged」メソッドの署名の後に構文「Handles dtpEndDate.ValueChanged」がある場合、aspx に「OnClick="dtpEndDate_ValueChanged"」などを記述する必要はありません。

WebFormsではなくWinFormsにいる間は、持っていないことを確認してください

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

または、Load メソッドまたは他の場所のどこかにそのようなものがあります。

それが役に立てば幸い、

イヴ

于 2013-03-15T11:50:10.060 に答える