【问题标题】:Get selected value from DateTimePicker从 DateTimePicker 获取选定的值
【发布时间】:2018-08-30 10:28:38
【问题描述】:

我想在 VB 中从DateTimePicker 中获取选定的值(如果我只选择日值,那么我想只获取选定的日值。)

在这张图片中,我从DateTimePicker 中选择了(蓝色标记的)年份值。所以我只需要今年的值。

TextBox 的情况下,我可以使用

TextEndTime.SelectedText

是否有任何语法或方法可以从 DateTimePicker 获取选定值?

【问题讨论】:

  • 所以这是一个 TextBox 对吧? DateTime 的格式是 yyyy/mm/dd?您想知道值的值和值的类型(年、月、日)吗?我想我有一个想法。如果我是正确的,那么也许我有一个解决方案。
  • 不,这是 DateTimePicker 。如果这是文本框,我想我可以使用上面的文本框选择方法进行选择。为了更清楚地说明此应用程序在平板电脑中使用,用户将选择年月或日并使用手动键盘进行更改。
  • 据我所知,没有托管 API。如果您从DateTimePicker 派生自己的类,您可能能够访问一些可能会有所帮助的受保护成员,但这只是一个猜测。我怀疑您需要使用 Windows API。我不确定,但我认为DateTimePicker 中有一个显示实际日期的编辑控件,您可以从中获取选定的文本,就像TextBox 一样。不确定具体细节,但这为您提供了研究途径。
  • 与 NumericUpDown 不同,DTP 的大部分内部都是内部的,因此您不能轻松地仅隔离 Text 控件以获取 SelectedText。也许可以使用 PInvoke 来获取文本,但如果我们知道所有这些的目的是什么,那么完全做其他事情可能会更容易。 DTP 的要点是强制选择有效日期。仅仅一年不是一个日期,所以也许应该使用其他东西
  • 我不知道这一切背后的业务需求。但看起来最简单的解决方案是捕获控件的图像并进行一些图像识别。我建议搜索解决方法(使用另一个控件或找到另一种方式来询问用户他的选择)

标签: vb.net winforms datetimepicker


【解决方案1】:

由于DateTimePicker-控件可以使用箭头键进行操作,您可以使用SendKeys来更改当前选定的值。

以下示例获取DateTimePicker 的当前DateTime-值,并在发送 键后将该值与新值进行比较。最后它将DateTimePicker 重置为原始值。
所以变量currSelected 将包含最后一个Selection

Dim currVal As DateTime
Dim newVal As DateTime
Dim valCheck As Boolean
Dim currSelected As Selection = Selection.None

Public Enum Selection
    None = 0
    Year = 1
    Month = 2
    Day = 3
End Enum

Private Sub CheckDTPSelection(dtp As DateTimePicker)
    valCheck = True
    currVal = dtp.Value
    SendKeys.Send("{UP}")
End Sub

Sub RefreshSelection(dtp As DateTimePicker)
    If valCheck Then
        newVal = dtp.Value

        If currVal.Year <> newVal.Year Then
            currSelected = Selection.Year
        ElseIf currVal.Month <> newVal.Month Then
            currSelected = Selection.Month
        ElseIf currVal.Day <> newVal.Day Then
            currSelected = Selection.Day
        End If

        dtp.Value = currVal
        valCheck = False
    End If
End Sub

Private Sub MyDateTimePicker_DropDown(sender As Object, e As EventArgs) Handles MyDateTimePicker.DropDown
    RemoveHandler MyDateTimePicker.MouseUp, AddressOf MyDateTimePicker_MouseUp
End Sub

Private Sub MyDateTimePicker_CloseUp(sender As Object, e As EventArgs) Handles MyDateTimePicker.CloseUp
    AddHandler MyDateTimePicker.MouseUp, AddressOf MyDateTimePicker_MouseUp
    CheckDTPSelection(MyDateTimePicker)
End Sub

Private Sub MyDateTimePicker_KeyUp(sender As Object, e As KeyEventArgs) Handles MyDateTimePicker.KeyUp
    If e.KeyValue = Keys.Left OrElse e.KeyValue = Keys.Right Then
        CheckDTPSelection(MyDateTimePicker)
    End If
End Sub

Private Sub MyDateTimePicker_MouseUp(sender As Object, e As MouseEventArgs) Handles MyDateTimePicker.MouseUp
    CheckDTPSelection(MyDateTimePicker)
End Sub

Private Sub MyDateTimePicker_ValueChanged(sender As Object, e As EventArgs) Handles MyDateTimePicker.ValueChanged
    Dim dtp As DateTimePicker = DirectCast(sender, DateTimePicker)

    RefreshSelection(dtp)
End Sub

Private Sub Btn_WhatsSelected_Click(sender As Object, e As EventArgs) Handles Btn_WhatsSelected.Click
    'Show the current selected value in a MessageBox
    MessageBox.Show(currSelected.ToString())
End Sub

【讨论】:

  • 这很聪明!为什么我没有想到呢? :D 不过有两点:1) 我也会在Enter 事件中添加CheckDTPSelection(以不使用鼠标 捕获第一个焦点)。 2)打开下拉会触发MouseUp,发送一个向上的按钮,改变视觉上选择的日/月;所以我会删除DropDown 中的MouseUp 处理程序,然后在CloseUp 中重新添加它。如果您不介意,让我将这些更改添加到您的答案中。
  • 刚刚发现使用Enter 事件会导致之前由MouseUp 引起的相同问题并且它在DropDown 之前触发(显然) i>,所以我暂时不会使用Enter
  • SendKeys 的问题是,如果由于某种原因键盘焦点发生变化,它可能会失败。
  • @AhmedAbdelhameed - 绝对。当您在数千台 PC 上运行生产代码时,这是一种很难识别和检测的错误。竞争条件发生在现实世界中。例如,如果某个应用因某种原因被阻止,而用户到处点击,那么一小段时间可能会变成几秒钟,并且可以将按键发送到另一个应用。
  • @SimonMourier 我同意,你说得很好。也就是说,我相信这将取决于开发人员根据他将要开发的应用程序的类型/大小来决定这是否可以接受。实际上,我不喜欢SendKeys,但考虑到似乎没有其他选择(除了创建自己的 DTP),我不会“讨厌”太多:D跨度>
【解决方案2】:

大家好,感谢您提供的关于可以操作 DateTimePicker 控件的提示。 我遇到了 DateTimePicker 的选择问题,当前选定的项目值无法发送到文本框,因为 DTP 仅适用于 valuechanged 事件。我花了 4 个小时的时间寻找解决方案并编写了以下代码:

Public MyEventCounter As Integer = 0

Private Sub DTPAcquDt_DropDown(sender As Object, e As EventArgs) Handles DTPAcquDt.DropDown
        RemoveHandler DTPAcquDt.MouseUp, AddressOf dtpacqudt_closeup
End Sub
Private Sub dtpacqudt_closeup(sender As Object, e As EventArgs) Handles DTPAcquDt.CloseUp
        AddHandler DTPAcquDt.MouseUp, AddressOf dtpacqudt_closeup
        'Check the Mouse/Keys event counter
        If MyEventCounter > 0 Then
            TxtDtAcqu.Text = DTPAcquDt.Value
            'RESET The Counter
            MyEventCounter = 0
        End If
End Sub
Private Sub DTPAcquDt_KeyUp(sender As Object, e As KeyEventArgs) Handles DTPAcquDt.KeyUp
        If e.KeyValue = Keys.Left OrElse e.KeyValue = Keys.Right Then
            MyEventCounter = MyEventCounter + 1
        End If
End Sub
Private Sub DTPAcquDt_MouseUp(sender As Object, e As MouseEventArgs) Handles DTPAcquDt.MouseUp
        MyEventCounter = MyEventCounter + 1
End Sub
Private Sub DTPAcquDt_ValueChanged(sender As Object, e As EventArgs) Handles DTPAcquDt.ValueChanged
        TxtDtAcqu.Text = DTPAcquDt.Value
        'RESET The Counter
        MyEventCounter = 0
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    • 2014-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多