سؤال

يتعلق هذا السؤال بوظائف محددة أن عميل طلب طلب لي تطبيق تصميمه. في الأساس، يريد العميل أن يدفع DateTimePicker سؤالا بعد تحديد التاريخ.

ومع ذلك، فإن هذا يبدو بسيطا، وأواجه صعوبات في إنجاز هذه المهمة البسيطة.

  1. إذا كنت موجه onlloseup - لن تنفذ إدخالات لوحة المفاتيح هذا الحدث
  2. إذا كنت موجه onvaluechanged - حرائق الأحداث في كل مرة يتم فيها تغيير التاريخ
  3. إذا كنت موجه onleave - حرائق الحدث إلى حد ما. لا ينطلق عند النقر فوق Toolstrip على سبيل المثال. أرغب في تجنب هذه الطريقة، حيث أن الحرائق فقط بمجرد النقر فوق المستخدم بعيدا عن عنصر التحكم.

في الأساس، أحاول التفكير في أفضل طريقة لموجه المستخدم بعد تحديد تاريخ من عنصر تحكم DatetimeMepicker.

ليس لدي أي مشاكل في بناء عنصر تحكم مخصص أيضا. لقد بدأت في جعل واحدة منذ أن كنت بحاجة أيضا للسماح بالقيم الفارغة.

هل كانت مفيدة؟

المحلول 3

انتهى بي الأمر ترميز عنصر تحكم مخصص للتعامل مع هذه الطريقة الصحيحة. قمت بإنشاء مربع نص مع زر، وأضاف عنصر تحكم Monthcalendar أيضا.

يقوم زر TextBox + فتح عنصر التحكم Monthcalendar. الطريقة الوحيدة لاختيار DateTime الآن هي عبر 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

نصائح أخرى

"حدد تاريخ" يعني:

  1. اختيار تاريخ مع الماوس، أو
  2. أدخل / تغيير تاريخ مع لوحة المفاتيح ثم نقل التركيز إلى عنصر تحكم آخر.

لذلك، ماذا عن مزيج من OnCloseUp و OnValidate/OnLeave?

ابدأ بمشاهدة OnValueChanged الأحداث. تعيين العلم المتغير إذا حرائق واحدة.

إذا حددوا باستخدام الماوس، فيمكنك إحضار المطالبة OnCloseUp وإعادة تعيين العلم الذي تم تغييره. ثم مشاهدة ل OnValueChanged الأحداث مرة أخرى.

متي OnValidate أو OnLeave حرائق، ويتم تعيين علمك (يفترض بعد تغيير التاريخ مع لوحة المفاتيح)، ثم إحضار المطالبة.

أود استخدام الحدث Onvaluechanged. بعد تغيير القيمة، اسأل السؤال. إذا أجبوا خطأ (مثال - س: هل أنت متأكد؟ ج: رقم) ثم إعادة تعيين Deasepicker والعودة التركيز عليه.

هذا المثال هو فوضوي قليلا ولكنه يعمل.

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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top