这是应用程序的设计:
这就是我向上或向下使用滚动条时发生的情况:
复选框在面板内,面板是透明的(很明显),只有表单使用背景图像。
为什么会发生这种失真以及如何解决问题?
PS:如果您需要更多信息或所有表格或其他内容,请告诉我。
这是应用程序的设计:
这就是我向上或向下使用滚动条时发生的情况:
复选框在面板内,面板是透明的(很明显),只有表单使用背景图像。
为什么会发生这种失真以及如何解决问题?
PS:如果您需要更多信息或所有表格或其他内容,请告诉我。
有效的解决方案是创建一个自定义面板(从控制面板继承的类),并使用 API 调用 LockWindowUpdate 和用于防止滚动闪烁的 OptimizedDoubleBuffer 属性制作锁定重绘的必要代码。
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
就像 Visual Basic 的一个普通面板,它继承了面板的所有属性,除非你编写程序来做你想做的事情。请注意,您必须在控制栏中显示为一个控件,称为“MyPanel”,然后将其重命名为您想要的。要以您控制的方式出现,您必须构建解决方案。
你把表格和瞧,你使用它。
乍一看,如果没有一些低级的调整,这似乎是不可能的。但我找到了一个“有点”的解决方法。
这是我的面板滚动事件处理程序中的 C# 代码。
private void panel1_Scroll(object sender, ScrollEventArgs e)
{
panel1.BackColor = System.Drawing.Color.Empty;
panel1.BackColor = System.Drawing.Color.Transparent;
}
由于此事件仅适用于您的滚动条,因此您希望在鼠标滚轮滚动上实现相同的操作。在 VB 中很简单,只需添加另一个函数即可。
这是完整的代码
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
而已。现在它在滚动条和鼠标滚轮上的工作方式相同。
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);
}
}