如何使DateTimePicker在鼠标滚轮上增加/减少

9
当您添加DateTimePicker控件时,可以选择控件值的一部分(例如月份),然后使用向上/向下箭头修改日期/时间值的这一部分(例如增加/减少月份)。
我想做的是允许使用鼠标滚轮进行相同的操作。我尝试在MouseWheel事件上注册,但我无法找到知道当前选择了日期/时间的哪个部分的方法,所以我无法知道是否应该增加时、日、月还是年。
有没有办法做到这一点?
6个回答

15

一种可能的、但不太优雅的解决方案是:

private void dateTimePicker1_MouseWheel(object sender, System.Windows.Forms.MouseEventArgs e)
{
    if (e.Delta > 0) 
    {
        System.Windows.Forms.SendKeys.Send("{UP}");
    } 
    else 
    {
        System.Windows.Forms.SendKeys.Send("{DOWN}");
    }
}

通常情况下这应该能正常工作,但在某些特殊情况下可能会产生意外结果(例如KeyDown/KeyUp事件被覆盖)。


非常感谢。实际上我自己也在尝试类似的东西,使用从DateTimePicker继承的用户控件,但不知道如何在MouseWheel事件处理程序中发送事件(尝试了this.OnKeyDown,但没有任何结果)。 - Ksempac
四年前世界是颠倒的,还是现在是颠倒的?我把函数反转以便在向下滚动时获得更高的值。 - Bitterblue

2

我也试图弄清楚这个问题。最终,我得出了以下结论:

Private Sub dtpDateTimePicker_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
    If e.Delta > 0 Then
        SendKeys.Send("{Up}")
    Else
        SendKeys.Send("{Down}")
    End If
End Sub

你可以使用以下方法将此处理程序自动添加到表单中的所有日期选择器及其容器中。只需在form_load中调用一次即可:
 Public Sub AttachDateTimeMouseWheels(ByRef ownerForm As Control)

    Dim myControl As Control        

    For Each myControl In ownerForm.Controls

        If TypeOf myControl Is DateTimePicker Then
            AddHandler myControl.MouseWheel, AddressOf dtpDateTimePicker_MouseWheel
        Else
            If myControl.Controls.Count > 0 Then
                AttachDateTimeMouseWheels(myControl)
            End If
        End If

    Next

End Sub

1
使用 sendmessage WM_KEYDOWN/WM_KEYUP。
    Private Sub DateTimePickerAlarm_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DateTimePickerAlarm.MouseWheel
        If e.Delta > 0 Then
            Native.User32.SendMessage(DateTimePickerAlarm.Handle, &H100, Keys.Up, &H1480001)
            Native.User32.SendMessage(DateTimePickerAlarm.Handle, &H101, Keys.Up, &HC1480001)
        Else
            Native.User32.SendMessage(DateTimePickerAlarm.Handle, &H100, Keys.Down, &H1500001)
            Native.User32.SendMessage(DateTimePickerAlarm.Handle, &H101, Keys.Down, &HC1500001)
        End If
        'msg=0x100 (WM_KEYDOWN) hwnd=0x???????? wparam=0x26 lparam=0x01480001 result=0x0
        'msg=0x101 (WM_KEYUP)   hwnd=0x???????? wparam=0x26 lparam=0xc1480001 result=0x0
        'msg=0x100 (WM_KEYDOWN) hwnd=0x???????? wparam=0x28 lparam=0x01500001 result=0x0
        'msg=0x101 (WM_KEYUP)   hwnd=0x???????? wparam=0x28 lparam=0xc1500001 result=0x0
    End Sub

0

不好意思,你没有回答我的问题。我知道如何获取增量(e.Delta对我来说已经足够了)。如果需要的话,我也知道光标在哪里(e.Location)。我需要知道的是当前选择了日期的哪一部分。例如,如果我的日期是YYYY MM DD,我需要知道用户选择了MM、DD还是YYYY,以便我可以递增它。例如,在文本框中,您可以获取选择的起始位置和长度。或者有一个函数可以给出最接近光标位置的索引。我没有想到DateTimePicker有类似的功能。 - Ksempac

0
如果您将 ShowUpDown 属性设置为 True,则会获得一个旋转框而不是下拉菜单,这将修改日期的突出显示部分。但我刚才发现,无论是否将此属性设置为 true,上下箭头键都会改变日期的突出显示部分,因此这没有意义。
如果您能找到这段代码,您应该也可以让鼠标滚轮正常工作。我会看看并尽力寻找。
更新:
我刚才发现了关于 ShowCheckBox 属性的说明:

可读/可写。如果为 true,则在控件中的日期时间值左侧显示复选框。当选中此复选框时,用户可以通过突出日期的一部分并按箭头键来在运行时更改控件中的值。当未选中时,只能通过单击下拉菜单来更改日期。默认值为 false。

这有用吗?
更新2:
我没有找到任何处理 DateTimePicker 的特定方面的代码。Microsoft 还发布这些控件的代码吗?

不,我已经将ShowCheckBox设置为true(因为我需要复选框)。所以,就像我说的那样,我可以使用上/下箭头修改值。现在我想做的是,用鼠标滚轮实现相同的行为(使用上/下很令人沮丧)。问题是,我找不到一种方法来获取我的控件中哪个部分被突出显示。 - Ksempac
我在过去的两年里断断续续地使用.NET,但从没看过微软内部的任何代码。我只是看到了一些他们如何使用所提供API的示例。如果你想要实现自己的行为,你需要自己找出应该使用的"魔法"。 - Ksempac
@Ksempac - 回到 Visual C++ 和 MFC 的遥远过去,你曾经能够获取一些 MFC 源代码 - 这是帮助解决问题的无价之宝。微软似乎已经停止了这种做法,除非我还没有找到它。 - ChrisF

0

我不确定,但这个方向是否好。

在日期选择器控件中,如果没有自定义格式,月份的x坐标小于日期的x坐标,日期的x坐标小于年份的x坐标,因为它们沿着递增的x轴显示。

然后,我们可以捕获dateTimePicker1_MouseDown事件,并将我们点击的x坐标设置为一个变量,比如xCordOfClick,然后在Fiur的鼠标滚轮代码中使用它来增加基于我们点击位置和日期选择器的x位置之间的差异。

类似于:

在dateTimePicker1_MouseDown(object sender, MouseEventArgs e)中

    {
        xCordOfClick  = e.X;
    }

在鼠标滚轮事件中

    {   
        //Do increment based on how far we clicked from the location of the control   
      // increment based on (xCordOfClick   - dateTimePicker1.Location.X).ToString() );
    }

我使用自定义格式,但这不是问题,因为我是设置它的人。我确实考虑过像这样的东西,但我想避免它,因为它依赖于假设,比如警察的大小或用于确定我们在控制中的位置的格式。 - Ksempac
我同意,这是一种比较原始的做法,更像是屏幕抓取的世界 :) .. 不过问题不错。 - AB.

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