平滑滚动.net表格

时间:2009-09-15 00:03:07

标签: c# .net winforms repaint

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

有没有人在此之前处理过这个问题?

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

任何线索?

4 个答案:

答案 0 :(得分:5)

将它弹出到你的班级(UserControl,Panel等)中,然后它会用拇指拖动。

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

答案 1 :(得分:4)

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

答案 2 :(得分:2)

尝试将表单的DoubleBuffered属性设置为True。

更新:实际上,由于您的控件位于表单上的Panel上,因此可能无法执行任何操作。内置的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 ...”开头的行上进行barf。删除此行并重建。

您现在可以在表单上使用DBPanel控件代替常规Panel,这应该可以解决您的闪烁问题。

更新2 :抱歉,我没有仔细阅读您的问题。你是对的,在你放开滚动条的拇指之前,Panel不会重绘。我认为要达到这个效果,你只需要创建自己的UserControl。

基本上你只有一个带有VScrollBar的UserControl停靠在右边,而一个带有AutoScroll = false的Panel停靠在左边,占用了剩余的空间。当您向上和向下移动拇指时,VScrollBar的Scroll和ValueChanged事件会激活,因此在向内部面板添加一堆LinkLabel后,您可以使用这些事件来更改Panel的顶部位置,从而实现动态滚动效果你正在寻找。

如果Panel默认不以这种方式工作,或者甚至有一个启用它的设置,这有点令人恼火。

答案 3 :(得分:0)

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


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