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 by the KeyDown, KeyUp events to keep track of when the shift key is pressed.
However, how do I actually trigger the horizontal scrolling? I am aware of WM_MOUSEHWHEEL, can that be used to trigger the event?
Update:
For a System.Windows.Form
there is a HorizontalScroll
property that is of type HScrollProperties
. You can manipulate the Value
attribute on that object to change the horizontal scrollbar's position. However, so far I haven't spotted any other controls on which that object is available.
First, if you have the horizontal scroll bar displayed and you have the mouse pointer over that scroll bar, then the mouse wheel will scroll horizontally.
Horizontal scrolling can be achieved by clicking and dragging a horizontal scroll bar, swiping sideways on a desktop trackpad or trackpad mouse, pressing left and right arrow keys, or swiping sideways with one's finger on a touchscreen.
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);
}
}
If a control has AutoScroll
and is displaying scrollbars, when you scroll the mouse wheel you will get the following behaviour:
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).
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?
Use Alvin's solution if possible. It's way better.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With