Reputation: 20464
This is the design of the app:
And this is what happens when i use the scrollbar up or down:
the checkboxes are inside a panel, the panel is transparent (obvious) only the form uses the background image.
why happens that distortion and how I can resolve the problem?
PS: If you need more information or all the form or something just tell me.
Upvotes: 0
Views: 4963
Reputation: 4748
the solution that worked, is to create a custom panel (a class that inherits from the control panel), and in making the necessary code to lock the redraw, with the api call LockWindowUpdate and OptimizedDoubleBuffer property that is used to prevent flickering the scrolling.
Public Class MyPanel
Inherits Panel
Public Sub New()
Me.AutoScroll = True
Me.SetStyle(ControlStyles.SupportsTransparentBackColor, True)
Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
End Sub
Private mImage As Image
Public Property Image() As Image
Get
Return mImage
End Get
Set(ByVal value As Image)
mImage = value
Invalidate()
End Set
End Property
Protected Overrides Sub OnScroll(ByVal se As ScrollEventArgs)
If se.Type = ScrollEventType.First Then
LockWindowUpdate(Me.Handle)
ElseIf se.Type = ScrollEventType.ThumbTrack OrElse se.Type = ScrollEventType.ThumbPosition Then
LockWindowUpdate(IntPtr.Zero)
Me.Refresh()
LockWindowUpdate(Me.Handle)
Else
LockWindowUpdate(IntPtr.Zero)
Me.Invalidate()
End If
MyBase.OnScroll(se)
End Sub
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
Console.WriteLine(e.ClipRectangle.ToString())
Using br As New SolidBrush(Me.BackColor)
e.Graphics.FillRectangle(br, Me.ClientRectangle)
End Using
If mImage IsNot Nothing Then
e.Graphics.DrawImage(mImage, 0, 0)
End If
MyBase.OnPaint(e)
End Sub
<DllImport("user32.dll")> _
Private Shared Function LockWindowUpdate(ByVal hWnd As IntPtr) As Boolean
End Function
End Class
is like a common panel of Visual Basic, it inherits all the properties of the panel, unless you program in to do what you want. Note that you have to appear like a control in the control bar, called "MyPanel" then rename it to the one you want. to appear as you control, you have to build the solution.
you put on the form and voila, you use that.
Upvotes: 2
Reputation: 26511
At first glance it seems that this is impossible without some low-level tweaking. But I've found a "somewhat" workaround.
This is my C# code inside my panel scroll event handler.
private void panel1_Scroll(object sender, ScrollEventArgs e)
{
panel1.BackColor = System.Drawing.Color.Empty;
panel1.BackColor = System.Drawing.Color.Transparent;
}
Since this event will only work on your scroll bars you want to implement same thing on mouse wheel scroll. In VB it is very simple, just add another function.
This is full code
Private Sub Panel1_Scroll(sender As Object, e As ScrollEventArgs) Handles Panel1.Scroll
Panel1.BackColor = System.Drawing.Color.Empty
Panel1.BackColor = System.Drawing.Color.Transparent
End Sub
Private Sub Panel1_MouseScroll(sender As Object, e As MouseEventArgs) Handles Panel1.MouseWheel
Panel1.BackColor = System.Drawing.Color.Empty
Panel1.BackColor = System.Drawing.Color.Transparent
End Sub
That's it. Now it works the same on scroll bars and mouse wheel.
Upvotes: 2
Reputation: 941635
The ScrollableControl class, the parent of Panel, doesn't override the OnPaintbackground() method like it should to draw the image correctly. The combination with the "Show window contents while dragging" option that's turned on for all modern Windows versions makes a mess of it.
Add a new class to your project and paste the code shown below. Compile. Drag the new control from the top of the toolbox onto your form, replacing the old one.
using System;
using System.Windows.Forms;
class MyPanel : Panel {
public MyPanel() {
this.DoubleBuffered = true;
}
protected override void OnPaintBackground(PaintEventArgs e) {
if (this.BackgroundImage != null) {
e.Graphics.TranslateTransform(this.AutoScrollPosition.X, this.AutoScrollPosition.Y);
e.Graphics.Clear(this.BackColor);
e.Graphics.DrawImage(this.BackgroundImage, 0, 0);
}
else base.OnPaintBackground(e);
}
}
Upvotes: 1