平滑滚动.net 表单

发布于 2024-08-05 07:07:23 字数 281 浏览 6 评论 0原文

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

以前有人处理过这个吗?

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

有任何线索吗?

Hi I am using forms in .net and i am adding lots of linked labels dynamically during runtime,
I am adding these linklabels to panel and adding that panel to the winform. When the no of linklabels increases the form puts out an auto scrollbar(vertical)...
Now when i scroll down using that autoscroll the form is not updating its view as i scroll, the form gets refreshed only when i stop scrolling...
Also when it refresh it looks too bad.. i can see how it draws slowly....

Has anyone dealt with this before??

I tried form.refresh() in scroll event handler but that doesn't seem to help..

Any clues?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

匿名。 2024-08-12 07:07:23

将其弹出到您的类(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);
}

Pop this into your class (UserControl, Panel, etc) , then it will work with thumb drag.

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);
}
撩心不撩汉 2024-08-12 07:07:23

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

If you don't want to use WinAPI calls, you can do this:

// 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;
    }
}
浪漫之都 2024-08-12 07:07:23

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

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

Try setting your form's DoubleBuffered property to True.

Update: actually, that probably won't do anything since your controls are on a Panel on your Form. The built-in Panel control doesn't have an exposed DoubleBuffered property, so the way to do it is to add a UserControl name DBPanel to your project, and change the code so that it inherits from Panel instead of UserControl (you can change this manually in the CS file after you add it). When you add the UserControl, the code will look like this:

public partial class DBPanel : UserControl
{
    public DBPanel()
    {
        InitializeComponent();
    }
}

Edit it so that it looks like this (change UserControl to Panel and add the "this.DoubleBuffered = true;" line to the constructor):

public partial class DBPanel : Panel
{
    public DBPanel()
    {
        InitializeComponent();
        this.DoubleBuffered = true;
    }
}

When you build the project, the compiler will barf on a line that begins with "this.AutoScaleMode ... ". Delete this line and rebuild.

You can now use the DBPanel control on your form in place of a regular Panel, and this should take care of your flicker problem.

Update 2: sorry, I didn't read your question closely enough. You're right, the Panel doesn't redraw itself until you let go of the scrollbar's thumb. I think to achieve this effect you'll just have to create your own UserControl.

Basically you'd just have a UserControl with a VScrollBar docked on the right, and a Panel with AutoScroll = false docked on the left taking up the remainder of the space. The Scroll and ValueChanged events of the VScrollBar fire as you move the thumb up and down, so after adding a bunch of LinkLabels to the inner Panel you can use these events to change the Top position of the Panel, and thus achieve the dynamic scrolling effect you're looking for.

It's kind of irritating that the Panel doesn't work this way by default, or even have a setting that enables it.

这样的小城市 2024-08-12 07:07:23

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


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

The simplest way is to refresh the panel during the scroll event.


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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文