【问题标题】:How to scroll Panel by keyboard?如何通过键盘滚动面板?
【发布时间】:2019-08-01 20:58:45
【问题描述】:

在一个表单中,我有一个 Panel,其中包含一个 PictureBox,仅此而已。要求之一是用户应该能够仅使用键盘滚动浏览该面板的内容。换句话说,他们首先需要使用 Tab 键进入面板,然后使用 Up/Down 或 PageUp/PageDown 键进行滚动。

根据微软文档,

TabStop 属性对 Panel 控件没有影响,因为它是 容器对象。

这在尝试之后似乎是非常正确的。在查找 PictureBox 的 TabStop 属性时也是如此,它只是说

此属性与此类无关。

我尝试将VScrollBar 添加到面板并将其TabStop 设置为True,但这似乎没有任何作用。

达到预期效果的最佳方法是什么?

【问题讨论】:

    标签: c# vb.net winforms scroll panel


    【解决方案1】:

    您可以从Panel 派生并将其设为Selectable 并将其TabStop 设置为true。然后覆盖ProcessCmdKey 并处理箭头键滚动就足够了。不要忘记将其AutoScroll 也设置为true。

    可选面板 - 可通过键盘滚动

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

    【讨论】:

    • 我正要对此发表答案:) 略有不同:覆盖表单的ProcessCmdKey,您不需要自定义控件。可以使用面板的滚动条:(例如,var scrollBar = panel1.VerticalScroll;)并将滚动条设置为.Value 属性为[X, Y] +- [SmallChange, LargeChange]
    • @Jimi 有几点: •面板不可选择,你首先需要一种方法来选择它。 •表单还可能包含几个控件,箭头键对某些控件(如按钮)具有特定含义。这就是为什么我更喜欢从面板派生并使其可选择并将滚动逻辑嵌入派生面板中的原因。
    • 嗯,当然,我正准备做同样的事情。由于您已经发布了答案,我评论了一个替代方案。当然,这意味着光标键仅用于滚动面板(如果您不想让代码更复杂一点)。
    • @Jimi 感谢您的反馈。我添加了if (!Focused) return base.ProcessCmdKey(ref msg, keyData); 让可能的子控件使用他们自己的键处理,以防Panel 没有集中。
    • 很好的解决方案:) 出于好奇,你为什么在这里设置ControlStyles.UserMouseControlStyles.Selectable 还不足以让 Panel 使用鼠标滚轮滚动吗?
    猜你喜欢
    • 2019-11-03
    • 1970-01-01
    • 1970-01-01
    • 2015-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    相关资源
    最近更新 更多