从DateTimePicker获取所选值

7

我希望从VB的DateTimePicker中获取所选值(如果我只选择了日期,则只需获取所选日期值。)

enter image description here

在此图像中,我已从此DateTimePicker中选择了(蓝色标记)年份值。因此,我只需要这个年份值。

对于TextBox,我可以使用以下方法获取所选值

TextEndTime.SelectedText

有没有获取 DateTimePicker 选中值的语法或方法?

@Ahmed Abdelhameed 我尝试向DTP发送DTM_GETDATETIMEPICKERINFO消息。它返回一个DATETIMEPICKERINFO,其中应该包含底层编辑控件的句柄(以尝试发送EM_GETSEL消息)。但是它没有返回它(为空)。然而,复选框和上下按钮(如果有)的位置被返回了。所以,你可以获取控件的屏幕截图...(是的,这很疯狂 :)) - Jimi
@MirJibon,这是一篇旧文章,与您想要实现的内容有些相关:http://www.vbforums.com/showthread.php?573148-RESOLVED-Select-part-of-DateTimePicker-in-code - dj079
1
与NumericUpDown不同,DTP的大部分内部都是内部的,因此您无法轻松地隔离文本控件以获取所选文本。 也许可以使用PInvoke来获取文本,但如果我们知道所有这些的目的,可能更容易做其他事情。 DTP的重点是强制选择有效日期。 只有年份不是日期,因此可能应该使用其他内容。 - Ňɏssa Pøngjǣrdenlarp
1
我不知道所有这些背后的业务需求。但是看起来最简单的解决方案是捕获控件的图像并进行一些图像识别。我建议寻找一个解决方法(使用另一个控件或找到另一种方式询问用户的选择)。 - Marco Guignard
通常情况下,您不应该依赖于控件的未记录特性。因为无法保证该特性始终保持不变。 - Reza Aghaei
显示剩余11条评论
2个回答

3
作为DateTimePicker控件可以使用箭头键进行操作,您可以使用SendKeys更改当前选定的值。 以下示例获取DateTimePicker的当前DateTime值,并在发送↑键后将值与新值进行比较。最后将DateTimePicker重置为原始值。 因此,变量currSelected将包含最后一个选择。
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中重新添加它。如果您不介意,让我将这些更改添加到您的答案中。 - 41686d6564 stands w. Palestine
刚刚发现使用 Enter 事件会导致之前由 MouseUp 引起的相同问题 并且 它在 DropDown 之前触发 (显然), 所以我暂时不会使用 Enter - 41686d6564 stands w. Palestine
SendKeys的问题在于,如果键盘焦点发生变化,它可能会失败。 - Simon Mourier
@SimonMourier 如果dtp.Focused Then SendKeys.Send("{UP}")?此外,我认为只有在DTP获得焦点时才会调用CheckDTPSelection。除非你是在谈论调用该方法和执行SendKeys.Send()之间非常短的时间段。 - 41686d6564 stands w. Palestine
4
@AhmedAbdelhameed - 当你在成千上万台计算机上运行生产代码时,这种 bug 是非常难以识别和检测的。竞态条件在现实世界中经常发生。例如,如果某个应用因某种原因被阻塞,而用户正在到处点击,一个短暂的时间可能会变成几秒钟,然后按键事件就可能被发送到另一个应用程序。 - Simon Mourier
2
@SimonMourier 我同意,你说得很有道理。话虽如此,我认为这取决于开发人员根据他/她所要开发的应用程序的类型/大小来决定是否接受这种方法。实际上,我不喜欢 SendKeys,就像你一样,但考虑到似乎没有其他选择(除了创建自己的 DTP),我不会太过“憎恨”它 :D - 41686d6564 stands w. Palestine

0
大家好,感谢您们提供的关于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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接