平滑滚动.net 表单

问题描述 投票:0回答:4

您好,我正在 .net 中使用表单,并且在运行时动态添加大量链接标签, 我将这些链接标签添加到面板并将该面板添加到 winform。当链接标签的数量增加时,表单会显示一个自动滚动条(垂直)... 现在,当我使用自动滚动向下滚动时,表单在滚动时不会更新其视图,只有当我停止滚动时表单才会刷新...... 另外,当它刷新时,它看起来太糟糕了..我可以看到它是如何缓慢绘制的....

以前有人处理过这个问题吗?

我在滚动事件处理程序中尝试了 form.refresh() 但这似乎没有帮助..

有什么线索吗?

c# .net winforms repaint
4个回答
6
投票

将其弹出到您的类(用户控件、面板等)中,然后它将通过拇指拖动来工作。

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

6
投票

如果你不想使用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;
    }
}

2
投票

尝试将表单的 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 位置,从而实现动态滚动效果你正在寻找。

令人恼火的是,面板默认情况下不以这种方式工作,甚至没有启用它的设置。


0
投票

最简单的方法是在滚动事件期间刷新面板。


private void panel1_Scroll(object sender, ScrollEventArgs e)
{
        panel1.Refresh();
}

© www.soinside.com 2019 - 2024. All rights reserved.