DateTimePicker控件在特定场景下的使用

发布于 2024-07-13 09:41:15 字数 464 浏览 13 评论 0原文

这个问题与客户为我正在设计的应用程序请求的特定功能有关。 基本上,客户希望 DateTimePicker 在选择日期后提示问题。

这听起来很简单,但是,我很难完成这个简单的任务。

  1. 如果我提示 OnCloseUp - 键盘输入将不会执行此事件
  2. 如果我提示 OnValueChanged - 每次日期触发该事件 更改了
  3. 如果我提示 OnLeave - 事件会稍微触发。 不触发时 例如,单击工具条。 我想避免使用这种方法,因为它仅在用户单击远离控件时触发。

所以基本上,我试图想出在用户从 dateTimePicker 控件中选择日期后提示用户的最佳方法。

我对构建自定义控件也没有任何问题。 我已经开始制作一个,因为我还需要允许 NULL 值。

This question is relating to a specific functionality that a client has requested for an application I am designing. Basically, the client wants the DateTimePicker to prompt a question after the date was selected.

This sounds simple, however, I am having difficulties accomplishing this simple task.

  1. If I prompt OnCloseUp - Keyboard entries will not execute this event
  2. If I prompt OnValueChanged - Event fires every time the date is
    changed
  3. If I prompt OnLeave - Event fires somewhat. Does not fire when
    toolstrip is clicked for example. I would like to avoid this method, as it only fires once the user clicks away from the control.

So basically, I am trying to think of the best way to prompt a user AFTER they select a date from a dateTimePicker control.

I have no issues with building a custom control either. I have started making one since I also needed to allow NULL values.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

墨落成白 2024-07-20 09:41:16

“选择日期”是指:

  1. 用鼠标选择日期,或
  2. 用键盘输入/更改日期,然后将焦点移至另一个控件。

那么,将 OnCloseUpOnValidate/OnLeave 结合起来怎么样?

首先观察 OnValueChanged 事件。 如果发生火灾,请设置一个已更改的标志。

如果他们用鼠标选择,您可以使用 OnCloseUp 弹出提示并重置更改的标志。 然后再次观察 OnValueChanged 事件。

OnValidateOnLeave 触发时,并且设置了您的标志(可能是在使用键盘更改日期之后),然后调出提示。

"Select a date" means:

  1. Choose a date with the mouse, or
  2. Enter/change a date with the keyboard then move focus to another control.

So, how about a combination of OnCloseUp and OnValidate/OnLeave?

Start by watching for OnValueChanged events. Set a changed flag if one fires.

If they select with the mouse, you can bring up the prompt with OnCloseUp and reset your changed flag. Then watch for OnValueChanged events again.

When OnValidate or OnLeave fires, and your flag is set (presumably after changing the date with the keyboard), then bring up the prompt.

相思故 2024-07-20 09:41:16

我会使用 OnValueChanged 事件。 他们更改值后,提出问题。 如果他们回答错误(示例 - 问:您确定吗?答:否。),则重置日期选择器并将焦点返回到它。

这个例子有点乱,但是很有效。

Private is_reset As Boolean = False
Private Sub DateTimePicker1_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DateTimePicker1.ValueChanged

    Dim answer As Integer
    If Not is_reset Then
        answer = MsgBox("Are you Sure?", MsgBoxStyle.YesNo)
        is_reset = False
    End If

    If answer = MsgBoxResult.No Then
        is_reset = True
        DateTimePicker1.Value = Now
        DateTimePicker1.Select()
    End If

I would use the OnValueChanged event. After they change the value, ask the question. If they answer wrong (Example - Q: Are you sure? A: No.) then reset the datepicker and return focus to it.

This example is a little messy but it works.

Private is_reset As Boolean = False
Private Sub DateTimePicker1_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DateTimePicker1.ValueChanged

    Dim answer As Integer
    If Not is_reset Then
        answer = MsgBox("Are you Sure?", MsgBoxStyle.YesNo)
        is_reset = False
    End If

    If answer = MsgBoxResult.No Then
        is_reset = True
        DateTimePicker1.Value = Now
        DateTimePicker1.Select()
    End If
み青杉依旧 2024-07-20 09:41:16

我最终编写了一个自定义控件来以正确的方式处理这个问题。
我创建了一个带有按钮的文本框,并添加了一个 MonthCalendar 控件。

文本框+按钮打开 MonthCalendar 控件。 现在选择日期时间的唯一方法是通过 MonthCalendar。 您无法从文本框中进行选择。 我还创建了一个在选择日期时触发的自定义事件。 它工作完美。 代码如下:

Public Class CustomDatePicker

  'Variables
  Friend WithEvents cal As MonthCalendar
  Private _isCalendarVisible As Boolean = False
  Private _currentSelectedDate As DateTime = Nothing

  'Events
  Public Event OnDateTimeSet(ByVal sender As Object, ByVal dateValue As DateTime)
  Public Event OnDateCleared(ByVal sender As Object)

  'Constructor
  Public Sub New()
    InitializeComponent()
  End Sub

  'Onload
  Private Sub CustomDatePicker_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    'Initially setup calendar
    cal = New MonthCalendar
    cal.Name = "Calendar"
    cal.MaxSelectionCount = 1
    cal.BringToFront()
    cal.Location = New Point(Me.Location.X + 5, Me.Location.Y + 25)
    Me.Parent.Controls.Add(cal)
    cal.Hide()
    _isCalendarVisible = False
  End Sub

  'Returns the currently selected date from the TextBox field
  Public ReadOnly Property CurrentSelectedDate()
    Get
      Return _currentSelectedDate
    End Get
  End Property

  'Display calendar
  Private Sub ShowCalendar()

    'Close any other custom date controls that are open on the parent form
    Dim cont As Control
    For Each cont In Parent.Controls
      If (cont.GetType().Name = "CustomDatePicker") Then
        CType(cont, CustomDatePicker).HideCalendar()
      End If
    Next

    'display the calendar
    If Not (_isCalendarVisible) Then
      tbxSelectedDate.BackColor = Color.Cornsilk
      cal.BringToFront()
      cal.Show()
      cal.Focus()
      _isCalendarVisible = True
      btnCalendarToggle.Checked = True
    End If

  End Sub

  'Hide the Calendar
  Private Sub HideCalendar()
    If (_isCalendarVisible) Then
      tbxSelectedDate.BackColor = Color.White
      cal.Hide()
      _isCalendarVisible = False
      btnCalendarToggle.Checked = False
      tbxSelectedDate.Focus()
    End If
  End Sub

  'Display the selected datetime into the textbox
  Private Sub SetDateTime()
    Me.tbxSelectedDate.Text = FormatDateTime(cal.SelectionRange.Start, DateFormat.LongDate)
    _currentSelectedDate = FormatDateTime(cal.SelectionRange.Start, DateFormat.LongDate)
    RaiseEvent OnDateTimeSet(Me, _currentSelectedDate)
  End Sub

  'Event when selection is made in the Calendar
  Private Sub Calendar_Selection(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DateRangeEventArgs) Handles cal.DateSelected
    SetDateTime()
    HideCalendar()
  End Sub

  'Handle the keyboard events associated with the calendar control
  Private Sub Calendar_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles cal.KeyPress
    If e.KeyChar = ChrW(Keys.Return) Then
      SetDateTime()
      HideCalendar()
    ElseIf e.KeyChar = ChrW(Keys.Escape) Then
      HideCalendar()
    End If
  End Sub

  'Handles keypresses on the textbox field
  Private Sub tbxSelectedDate_KeyUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles tbxSelectedDate.KeyUp
    If (e.KeyCode = Keys.Down) Then
      ShowCalendar()
    ElseIf (e.KeyCode = Keys.Delete) Then
      tbxSelectedDate.Text = ""
    End If
  End Sub

  'Show the calendar when button is clicked
  Private Sub btnCalendarToggle_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles btnCalendarToggle.MouseUp
    ToggleCalendar()
  End Sub

  'Show the calendar when button is 'clicked' via ENTER on keyboard
  Private Sub btnCalendarToggle_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles btnCalendarToggle.KeyPress
    If e.KeyChar = ChrW(Keys.Return) Then
      ToggleCalendar()
    End If
  End Sub

  'Toggle calender.  If on, turn off.  If off, turn on.
  Private Sub ToggleCalendar()
    If Not (_isCalendarVisible) Then
      ShowCalendar()
      btnCalendarToggle.Checked = True
    Else
      HideCalendar()
      btnCalendarToggle.Checked = False
    End If
  End Sub

  'When textbox value is changed, check to see if it was cleared.  If cleared, raiseevent.
  Private Sub tbxSelectedDate_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tbxSelectedDate.TextChanged
    If (tbxSelectedDate.Text = "") Then
      _currentSelectedDate = Nothing
      RaiseEvent OnDateCleared(Me)
    End If
  End Sub

I ended up coding a custom control to handle this the right way.
I created a textbox with a button, and added a MonthCalendar control as well.

The textbox+button opens the MonthCalendar control. The only way to choose the datetime now is via the MonthCalendar. You cannot select from the Textbox. I also created a custom event that fires when the date is selected. It works perfectly. Code below:

Public Class CustomDatePicker

  'Variables
  Friend WithEvents cal As MonthCalendar
  Private _isCalendarVisible As Boolean = False
  Private _currentSelectedDate As DateTime = Nothing

  'Events
  Public Event OnDateTimeSet(ByVal sender As Object, ByVal dateValue As DateTime)
  Public Event OnDateCleared(ByVal sender As Object)

  'Constructor
  Public Sub New()
    InitializeComponent()
  End Sub

  'Onload
  Private Sub CustomDatePicker_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    'Initially setup calendar
    cal = New MonthCalendar
    cal.Name = "Calendar"
    cal.MaxSelectionCount = 1
    cal.BringToFront()
    cal.Location = New Point(Me.Location.X + 5, Me.Location.Y + 25)
    Me.Parent.Controls.Add(cal)
    cal.Hide()
    _isCalendarVisible = False
  End Sub

  'Returns the currently selected date from the TextBox field
  Public ReadOnly Property CurrentSelectedDate()
    Get
      Return _currentSelectedDate
    End Get
  End Property

  'Display calendar
  Private Sub ShowCalendar()

    'Close any other custom date controls that are open on the parent form
    Dim cont As Control
    For Each cont In Parent.Controls
      If (cont.GetType().Name = "CustomDatePicker") Then
        CType(cont, CustomDatePicker).HideCalendar()
      End If
    Next

    'display the calendar
    If Not (_isCalendarVisible) Then
      tbxSelectedDate.BackColor = Color.Cornsilk
      cal.BringToFront()
      cal.Show()
      cal.Focus()
      _isCalendarVisible = True
      btnCalendarToggle.Checked = True
    End If

  End Sub

  'Hide the Calendar
  Private Sub HideCalendar()
    If (_isCalendarVisible) Then
      tbxSelectedDate.BackColor = Color.White
      cal.Hide()
      _isCalendarVisible = False
      btnCalendarToggle.Checked = False
      tbxSelectedDate.Focus()
    End If
  End Sub

  'Display the selected datetime into the textbox
  Private Sub SetDateTime()
    Me.tbxSelectedDate.Text = FormatDateTime(cal.SelectionRange.Start, DateFormat.LongDate)
    _currentSelectedDate = FormatDateTime(cal.SelectionRange.Start, DateFormat.LongDate)
    RaiseEvent OnDateTimeSet(Me, _currentSelectedDate)
  End Sub

  'Event when selection is made in the Calendar
  Private Sub Calendar_Selection(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DateRangeEventArgs) Handles cal.DateSelected
    SetDateTime()
    HideCalendar()
  End Sub

  'Handle the keyboard events associated with the calendar control
  Private Sub Calendar_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles cal.KeyPress
    If e.KeyChar = ChrW(Keys.Return) Then
      SetDateTime()
      HideCalendar()
    ElseIf e.KeyChar = ChrW(Keys.Escape) Then
      HideCalendar()
    End If
  End Sub

  'Handles keypresses on the textbox field
  Private Sub tbxSelectedDate_KeyUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles tbxSelectedDate.KeyUp
    If (e.KeyCode = Keys.Down) Then
      ShowCalendar()
    ElseIf (e.KeyCode = Keys.Delete) Then
      tbxSelectedDate.Text = ""
    End If
  End Sub

  'Show the calendar when button is clicked
  Private Sub btnCalendarToggle_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles btnCalendarToggle.MouseUp
    ToggleCalendar()
  End Sub

  'Show the calendar when button is 'clicked' via ENTER on keyboard
  Private Sub btnCalendarToggle_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles btnCalendarToggle.KeyPress
    If e.KeyChar = ChrW(Keys.Return) Then
      ToggleCalendar()
    End If
  End Sub

  'Toggle calender.  If on, turn off.  If off, turn on.
  Private Sub ToggleCalendar()
    If Not (_isCalendarVisible) Then
      ShowCalendar()
      btnCalendarToggle.Checked = True
    Else
      HideCalendar()
      btnCalendarToggle.Checked = False
    End If
  End Sub

  'When textbox value is changed, check to see if it was cleared.  If cleared, raiseevent.
  Private Sub tbxSelectedDate_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tbxSelectedDate.TextChanged
    If (tbxSelectedDate.Text = "") Then
      _currentSelectedDate = Nothing
      RaiseEvent OnDateCleared(Me)
    End If
  End Sub
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文