Shift + mouse wheel horizontal scrolling

后端 未结 3 748
无人共我
无人共我 2020-12-31 16:40

The use of shift + scroll wheel is fairly common for horizontal scrolling.

Both of those are fairly easy to capture. I can use the MouseWheel event with a flag set

相关标签:
3条回答
  • 2020-12-31 17:08

    In your designer file, you'll need to manually add a MouseWheel event delegate.

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

    Then, in your code behind, you can add the following.

        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);
            }
        }
    

    For more information on the const values, see the following SO: How do I programmatically scroll a winforms datagridview control?

    UPDATE

    Use Alvin's solution if possible. It's way better.

    0 讨论(0)
  • 2020-12-31 17:12

    The same code as provided by xixonia in 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
    
    0 讨论(0)
  • 2020-12-31 17:16

    If you are creating your own control derived from UserControl or ScrollControl or Form, you can use this simple solution:

    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);
        }
    }
    

    Explanation

    If a control has AutoScroll and is displaying scrollbars, when you scroll the mouse wheel you will get the following behaviour:

    1. If no scrollbars are enabled, it does nothing.
    2. If only vertical scrollbar is enabled, it scrolls vertical scrollbar.
    3. If only horizontal scrollbar is enabled, it scrolls horizontal scrollbar.
    4. If both vertical and horizontal scrollbars are enabled, it scrolls vertical scrollbar.

    Noticing this behaviour, I figured out this hack to override OnMouseWheel of the control, then if the vertical scrollbar is enabled and Shift is held down, it disables the vertical scrollbar before calling base.OnMouseWheel. This will trick the control in scrolling the horizontal scrollbar (behaviour 3 as shown above).

    0 讨论(0)
提交回复
热议问题