嗨,我在 .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 As 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 属性,所以这样做的方法是在您的项目中添加一个 UserControl 名称 DBPanel,并更改代码以便它继承自 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:抱歉,我没有仔细阅读您的问题。你是对的,在你松开滚动条的拇指之前,面板不会重绘自己。我认为要实现这种效果,您只需创建自己的 UserControl。
基本上,您只需要一个带有 VScrollBar 的 UserControl 停靠在右侧,而带有 AutoScroll = false 的 Panel 停靠在左侧,占据了剩余的空间。VScrollBar 的 Scroll 和 ValueChanged 事件在你上下移动拇指时触发,所以在内部 Panel 中添加一堆 LinkLabels 后,你可以使用这些事件来改变 Panel 的 Top 位置,从而实现动态滚动效果您正在寻找。
面板在默认情况下无法以这种方式工作,甚至没有启用它的设置,这有点令人恼火。
最简单的方法是在滚动事件期间刷新面板。
private void panel1_Scroll(object sender, ScrollEventArgs e)
{
panel1.Refresh();
}