今天遇到了一个问题,描述如下:
有一个Panel容器,将AutoScroll属性设置为True,此时Panel容器会在内容过多时自动展示一个滚动条。这个滚动条存在一个缺点,即会随着焦点变化自动滚向焦点位置。
如果仅初始化界面时Panel滚动条位置变化,可在赋值完毕后执行如下代码将滚动条滚回指定位置(其中pnlXXX为Panel的名字):
this.pnlXXX.VerticalScroll.Value = 0;
不过今天又遇到了另一个更加棘手的场景,我的一个控件需要使用Timer重复操作,操作间隔为1秒。如果焦点离开指定的Panel,Panel的滚动条会在1秒以内滚离位置。
有一个治标不治本的方法就是在Timer操作前记录位置并在操作后将滚动条滚回,代码如下:
System.Drawing.Point CurrentPoint;
CurrentPoint = pnlXXX.AutoScrollPosition;
//TODO:会触发滚动条位置变动的代码
pnlXXX.AutoScrollPosition = new Point(Math.Abs(pnlXXX.AutoScrollPosition.X), Math.Abs(CurrentPoint.Y));
这个方法有一个缺点,就是滚动条经过两次拉动后屏幕会有明显闪动,从用户体验的角度上说肯定是不合适的。
最后还是求助谷歌找到了一个最为稳妥的办法,重写Panel控件。此方法参考了这个页面的内容:
新建类PanelWithoutAutoScroll继承Panel,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace PanelScrollTest
{
class PanelWithoutAutoScroll : Panel
{
protected override System.Drawing.Point ScrollToControl(Control activeControl)
{
return DisplayRectangle.Location;
}
}
}
将Panel替换为PanelWithoutAutoScroll即可实现Panel的滚动条不随焦点变化而自动改变位置。
END