FatDaemon
FatDaemon

Reputation: 806

smooth scrolling .net forms

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?

Upvotes: 5

Views: 9623

Answers (4)

alldayremix
alldayremix

Reputation: 753

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)Panel;
    if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll) {
        p.HorizontalScroll.Value = e.NewValue;
    } else if (e.ScrollOrientation == ScrollOrientation.VerticalScroll) {
        p.VerticalScroll.Value = e.NewValue;
    }
}

Upvotes: 6

T.j. Duchene
T.j. Duchene

Reputation: 1

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


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

Upvotes: 0

CharlesW
CharlesW

Reputation: 625

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

Upvotes: 6

MusiGenesis
MusiGenesis

Reputation: 75296

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.

Upvotes: 2

Related Questions