Shift +鼠标滚轮水平滚动

时间:2011-10-19 21:05:45

标签: c# .net vb.net winforms

使用shift +滚轮对于水平滚动来说相当常见。

这两个都很容易捕获。我可以使用带有KeyDown,KeyUp事件设置的标志的MouseWheel事件来跟踪按下shift键的时间。

但是,我如何实际触发水平滚动?我知道WM_MOUSEHWHEEL,可以用来触发事件吗?

更新: 对于System.Windows.Form,有HorizontalScroll属性,类型为HScrollProperties。您可以操纵该对象上的Value属性来更改水平滚动条的位置。但是,到目前为止,我还没有发现任何其他可用对象的控件。

3 个答案:

答案 0 :(得分:11)

如果您要创建自己的控件,源自UserControlScrollControlForm,则可以使用此简单解决方案:

protected override void OnMouseWheel(MouseEventArgs e)
{
    if (this.VScroll && (Control.ModifierKeys & Keys.Shift) == Keys.Shift)
    {
        this.VScroll = false;
        base.OnMouseWheel(e);
        this.VScroll = true;
    }
    else
    {
        base.OnMouseWheel(e);
    }
}

说明

如果控件有AutoScroll并且正在显示滚动条,则滚动鼠标滚轮时会出现以下行为:

  1. 如果没有启用滚动条,则不执行任何操作。
  2. 如果仅启用垂直滚动条,则会滚动垂直滚动条。
  3. 如果仅启用水平滚动条,则会滚动水平滚动条。
  4. 如果同时启用了垂直和水平滚动条,则会滚动垂直滚动条。
  5. 注意到这种行为,我发现这个hack要覆盖控件的OnMouseWheel,然后如果启用垂直滚动条并按住 Shift ,它会在调用之前禁用垂直滚动条base.OnMouseWheel。这将在滚动水平滚动条时欺骗控件(行为3如上所示)。

答案 1 :(得分:4)

在您的设计器文件中,您需要手动添加MouseWheel事件委托。

this.richTextBox.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.RichTextBox_MouseWheel);

然后,在您的代码中,您可以添加以下内容。

    private const int WM_SCROLL = 276; // Horizontal scroll 
    private const int SB_LINELEFT = 0; // Scrolls one cell left 
    private const int SB_LINERIGHT = 1; // Scrolls one line right

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam); 

    private void RichTextBox_MouseWheel(object sender, MouseEventArgs e)
    {
        if (ModifierKeys == Keys.Shift)
        {
            var direction = e.Delta > 0 ? SB_LINELEFT : SB_LINERIGHT;

            SendMessage(this.richTextBox.Handle, WM_SCROLL, (IntPtr)direction, IntPtr.Zero);
        }
    }

有关const值的更多信息,请参阅以下SO:How do I programmatically scroll a winforms datagridview control?

更新

尽可能使用Alvin's solution 方式更好

答案 2 :(得分:1)

与xixonia在VB.NET中提供的相同代码

Private Const WM_SCROLL As Integer = 276 
Private Const SB_LINELEFT As Integer = 0 
Private Const SB_LINERIGHT As Integer = 1

<DllImport("user32.dll", CharSet:=CharSet.Auto)> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, 
                                    ByVal wMsg As UInteger,
                                    ByVal wParam As IntPtr, 
                                    ByVal lParam As IntPtr) As Integer
End Function

Private Sub RichTextBox_MouseWheel(ByVal sender As Object, ByVal e As MouseEventArgs) Handles RichTextBox1.MouseWheel

  If ModifierKeys = Keys.Shift Then
    Dim direction = If(e.Delta > 0, SB_LINELEFT, SB_LINERIGHT)
    SendMessage(Me.RichTextBox1.Handle, WM_SCROLL, CType(direction, IntPtr), IntPtr.Zero)
  End If
End Sub