问题
Inside a form, I have a Panel
that contains a single PictureBox
and nothing else. One of the requirements is that the user should be able to scroll through the contents of that panel by using only the keyboard. In other words, they would first need to tab into the panel and then use the Up/Down or PageUp/PageDown keys to scroll.
According to the Microsoft Docs,
The TabStop property has no effect on the Panel control as it is a container object.
Which, after trying it out appears to be very true. It's similar when looking up a TabStop property for the PictureBox, where it just says
This property is not relevant for this class.
I tried adding a VScrollBar
to the panel and setting its TabStop
to True
, but that didn't seem to do anything.
What is the best way to achieve the desired effect?
回答1:
You can derive from Panel
and make it Selectable
and set its TabStop
to true. Then It's enough to override ProcessCmdKey
and handle arrow keys to scroll. Don't forget to set its AutoScroll
to true as well.
Selectable Panel - Scrollable by Keyboard
using System.Drawing;
using System.Windows.Forms;
class SelectablePanel : Panel
{
const int ScrollSmallChange = 10;
public SelectablePanel()
{
SetStyle(ControlStyles.Selectable, true);
SetStyle(ControlStyles.UserMouse, true);
TabStop = true;
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (!Focused)
return base.ProcessCmdKey(ref msg, keyData);
var p = AutoScrollPosition;
switch (keyData)
{
case Keys.Left:
AutoScrollPosition = new Point(-ScrollSmallChange - p.X, -p.Y);
return true;
case Keys.Right:
AutoScrollPosition = new Point(ScrollSmallChange - p.X, -p.Y);
return true;
case Keys.Up:
AutoScrollPosition = new Point(-p.X, -ScrollSmallChange - p.Y);
return true;
case Keys.Down:
AutoScrollPosition = new Point(-p.X, ScrollSmallChange - p.Y);
return true;
default:
return base.ProcessCmdKey(ref msg, keyData);
}
}
}
来源:https://stackoverflow.com/questions/55103670/how-to-scroll-panel-by-keyboard