-1

I have this weird scrolling/background bug in C# and VB.net. When I create a panel and I use Autoscroll the background isnt updating during scrolling. In the end it looks really weird (video: https://youtu.be/0vaO-zmWFmk) I tried the same with a TabControl and the background scrolled like it should. I tried external scrollbars and the same happened. And I tried VB.net too. I think this is a bug from Visual Studios and I would appreciate if someone could help me Thanks, LG!

zKeviin
  • 37
  • 4
  • Implement the panel's Scroll event, call the panel's Invalidate() method in the event handler. It does flicker like a cheap motel however if the image is not optimal, the subject of [this post](https://stackoverflow.com/a/32247482/17034). – Hans Passant Aug 17 '20 at 14:56
  • @HansPassant -- Is there anything wrong with my solution below? It doesn't flicker at all and has smooth scrolling. – Andy Aug 17 '20 at 15:37

1 Answers1

0

If you want the image to scroll with the scrollbar, you can do this easily by simply extending the Panel and overriding OnPaintBackground.

Keep in mind, if you do this, you must make the control DoubleBuffered (this is done for you in the code below).

In this example, I added in a "Tiled" option. So you could use one big image, or use a seamless tile and tile it (set via BackgroundImageLayout property. All other options will paint the same).

C#

using System.Drawing;
using System.Windows.Forms;

public class PanelEx : Panel
{
    public PanelEx()
    {
        DoubleBuffered = true;
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        if (BackgroundImage != null)
        {
            if (ImageLayout.Tile == BackgroundImageLayout)
            {
                for (int x = 0; x <= DisplayRectangle.Width;
                    x += BackgroundImage.Width)
                {
                    for (int y = 0; y <= DisplayRectangle.Height;
                        y += BackgroundImage.Height)
                    {
                        e.Graphics.DrawImage(BackgroundImage,
                            new Point(x - HorizontalScroll.Value,
                                y - VerticalScroll.Value));
                    }
                }
            }
            else
            {
                e.Graphics.DrawImage(BackgroundImage,
                    new Point(-HorizontalScroll.Value, -VerticalScroll.Value));
            }
        }
        else
        {
            base.OnPaintBackground(e);
        }
    }
}

How to use this

  1. Right-click on your project and in the menu select Add then Class. Name the class PanelEx.cs
  2. Copy and paste the code above in to that class file.
  3. In the form that has the panel you want to modify, go in to the designer file (Look at image below)
  4. Change all instances of System.Windows.Forms.Panel(); to PanelEx();
  5. Save, do a full rebuild and run.

panel install


VB.NET

Public Class PanelEx
    Inherits Panel

    Public Sub New()
        DoubleBuffered = True
    End Sub

    Protected Overrides Sub OnPaintBackground(e As PaintEventArgs)
        If Not BackgroundImage Is Nothing Then
            If BackgroundImageLayout = ImageLayout.Tile Then

                Dim x As Integer, y As Integer
                While x <= DisplayRectangle.Width
                    y = 0
                    While y <= DisplayRectangle.Height
                        e.Graphics.DrawImage(
                            BackgroundImage,
                            New Point(x - HorizontalScroll.Value,
                                      y - VerticalScroll.Value))
                        y += BackgroundImage.Height
                    End While
                    x += BackgroundImage.Width
                End While
            Else
                e.Graphics.DrawImage(BackgroundImage,
                                     New Point(-HorizontalScroll.Value,
                                               -VerticalScroll.Value))
            End If
        Else
            MyBase.OnPaintBackground(e)
        End If
    End Sub
End Class

How to use this

  1. Right-click on your project and in the menu select Add then Class. Name the class PanelEx.vb
  2. Copy and paste the code above in to that class file.
  3. In the form that has the panel you want to modify, go in to the designer file (Look at image below)
  4. Change all instances of Panel to PanelEx
  5. Save, do a full rebuild and run.

vb.net designer

Andy
  • 12,859
  • 5
  • 41
  • 56
  • Im kinda new to C# so I really dont understand what you just did, Normally I use VB. Could you please exlpain this or could you upload the Project? Here is my project to download: https://mega.nz/file/qgkEVYDC#wormT4OUlAzx5P5qf79K48L7PYYDTC1UUX6-H7VpuEA Its just a simple test program. The problem is in the video (https://youtu.be/0vaO-zmWFmk). It would be really helpful if you could fix my test program. I really appreciate that you try to help me, Thank you. LG – zKeviin Aug 17 '20 at 11:26
  • Wow, It actually worked. Thank you :) And is there a way to to do the same thing in VB.net? – zKeviin Aug 17 '20 at 17:00
  • @zKeviin -- I haven't written VB.NET code in 10 years, but I'll give it a shot :) – Andy Aug 17 '20 at 17:02
  • Thank you, I really appreciate that – zKeviin Aug 17 '20 at 17:05
  • @zKeviin -- added VB.NET example – Andy Aug 17 '20 at 17:44
  • 1
    And again, thank you! It works perfectly fine and now I can finally continue working on my program. Thank you :) – zKeviin Aug 17 '20 at 19:46