您好,我正在 .net 中使用表单,并且在运行时动态添加大量链接标签, 我将这些链接标签添加到面板并将该面板添加到 winform。当链接标签的数量增加时,表单会显示一个自动滚动条(垂直)... 现在,当我使用自动滚动向下滚动时,表单在滚动时不会更新其视图,只有当我停止滚动时表单才会刷新...... 另外,当它刷新时,它看起来太糟糕了..我可以看到它是如何缓慢绘制的....
以前有人处理过这个问题吗?
我在滚动事件处理程序中尝试了 form.refresh() 但这似乎没有帮助..
有什么线索吗?
将其弹出到您的类(用户控件、面板等)中,然后它将通过拇指拖动来工作。
private const int WM_HSCROLL = 0x114;
private const int WM_VSCROLL = 0x115;
protected override void WndProc (ref Message m)
{
if ((m.Msg == WM_HSCROLL || m.Msg == WM_VSCROLL)
&& (((int)m.WParam & 0xFFFF) == 5))
{
// Change SB_THUMBTRACK to SB_THUMBPOSITION
m.WParam = (IntPtr)(((int)m.WParam & ~0xFFFF) | 4);
}
base.WndProc (ref m);
}
如果你不想使用WinAPI调用,你可以这样做:
// Add event handler to an existing panel
MyPanel.Scroll += new EventHandler(MyPanelScroll_Handler);
// Enables immediate scrolling of contents
private void MyPanelScroll_Handler(System.Object sender, System.Windows.Forms.ScrollEventArgs e)
{
Panel p = (sender)Panel;
if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll) {
p.HorizontalScroll.Value = e.NewValue;
} else if (e.ScrollOrientation == ScrollOrientation.VerticalScroll) {
p.VerticalScroll.Value = e.NewValue;
}
}
尝试将表单的 DoubleBuffered 属性设置为 True。
更新:实际上,这可能不会做任何事情,因为您的控件位于表单的面板上。 内置的Panel控件没有公开的DoubleBuffered属性,因此实现的方法是在您的项目中添加一个名为DBPanel的UserControl,并更改代码,使其继承自Panel而不是UserControl(您可以更改此添加后手动添加到 CS 文件中)。 当您添加 UserControl 时,代码将如下所示:
public partial class DBPanel : UserControl
{
public DBPanel()
{
InitializeComponent();
}
}
编辑它,使其看起来像这样(将 UserControl 更改为 Panel 并将“this.DoubleBuffered = true;”行添加到构造函数):
public partial class DBPanel : Panel
{
public DBPanel()
{
InitializeComponent();
this.DoubleBuffered = true;
}
}
当您构建项目时,编译器将在以“this.AutoScaleMode ...”开头的行上吐出。 删除此行并重建。
您现在可以在表单上使用 DBPanel 控件来代替常规面板,这应该可以解决您的闪烁问题。
更新2:抱歉,我没有仔细阅读你的问题。 你是对的,在你放开滚动条的拇指之前,面板不会自动重绘。 我认为要实现这种效果,您只需创建自己的用户控件即可。
基本上,您只需将一个带有 VScrollBar 的 UserControl 停靠在右侧,将一个带有 AutoScroll = false 的面板停靠在左侧,占据剩余空间。 当您上下移动拇指时,VScrollBar 的 Scroll 和 ValueChanged 事件会触发,因此在向内部 Panel 添加一堆 LinkLabels 后,您可以使用这些事件来更改 Panel 的 Top 位置,从而实现动态滚动效果你正在寻找。
令人恼火的是,面板默认情况下不以这种方式工作,甚至没有启用它的设置。
最简单的方法是在滚动事件期间刷新面板。
private void panel1_Scroll(object sender, ScrollEventArgs e)
{
panel1.Refresh();
}