Vb.net 表单背景图像的视觉问题

Vb.net 表单背景图像的视觉问题,vb.net,image,visual-studio,visual-studio-2012,background-image,Vb.net,Image,Visual Studio,Visual Studio 2012,Background Image,这是应用程序的设计: 这就是当我向上或向下使用滚动条时发生的情况: 复选框位于面板内,面板是透明的(明显的),只有窗体使用背景图像 为什么会发生这种扭曲,我如何解决这个问题 PS:如果您需要更多信息或所有表单或其他信息,请告诉我。乍一看,如果没有一些低级的调整,这似乎是不可能的。但我找到了一个“有点”的解决办法 在面板上创建OnScroll事件 使用一些背景色(如黑色)重新绘制它,然后设置它 重新透明化 这是我的面板滚动事件处理程序中的C#代码 private void panel1_Scr

这是应用程序的设计:

这就是当我向上或向下使用滚动条时发生的情况:

复选框位于面板内,面板是透明的(明显的),只有窗体使用背景图像

为什么会发生这种扭曲,我如何解决这个问题


PS:如果您需要更多信息或所有表单或其他信息,请告诉我。

乍一看,如果没有一些低级的调整,这似乎是不可能的。但我找到了一个“有点”的解决办法

  • 在面板上创建OnScroll事件
  • 使用一些背景色(如黑色)重新绘制它,然后设置它 重新透明化
  • 这是我的面板滚动事件处理程序中的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
    

    就这样。现在,它在滚动条和鼠标滚轮上也能起到同样的作用。

    乍一看,如果没有一些低级的调整,这似乎是不可能的。但我找到了一个“有点”的解决办法

  • 在面板上创建OnScroll事件
  • 使用一些背景色(如黑色)重新绘制它,然后设置它 重新透明化
  • 这是我的面板滚动事件处理程序中的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
    

    就这样。现在,它在滚动条和鼠标滚轮上也可以工作。

    面板的父级ScrollableControl类不会像正确绘制图像那样重写OnPaintbackground()方法。与所有现代Windows版本都启用的“拖动时显示窗口内容”选项相结合,会把它搞得一团糟

    向项目中添加一个新类并粘贴如下所示的代码。编译。将新控件从工具箱顶部拖到窗体上,替换旧控件

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

    Panel的父级ScrollableControl类不会像正确绘制图像那样重写OnPaintbackground()方法。与所有现代Windows版本都启用的“拖动时显示窗口内容”选项相结合,会把它搞得一团糟

    向项目中添加一个新类并粘贴如下所示的代码。编译。将新控件从工具箱顶部拖到窗体上,替换旧控件

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

    有效的解决方案是创建一个自定义面板(一个从控制面板继承的类),并使用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
    
    公共类MyPanel
    继承面板
    公共分新()
    Me.AutoScroll=True
    Me.SetStyle(ControlStyles.SupportsTransparentBackColor,True)
    Me.SetStyle(ControlStyles.OptimizedDoubleBuffer,True)
    端接头
    私有镜像作为镜像
    公共属性图像()作为图像
    得到
    返回图像
    结束
    设置(ByVal值作为图像)
    图像=值
    使无效
    端集
    端属性
    受保护的覆盖子OnScroll(ByVal se作为ScrollEventArgs)
    如果se.Type=ScrollEventType.First,则
    LockWindowUpdate(Me.Handle)
    ElseIf se.Type=ScrollEventType.ThumbTrack或Else se.Type=ScrollEventType.ThumbPosition然后
    锁窗口更新(IntPtr.Zero)
    我
    LockWindowUpdate(Me.Handle)
    其他的
    锁窗口更新(IntPtr.Zero)
    使无效
    如果结束
    MyBase.OnScroll(东南)
    端接头
    受保护的覆盖子OnPaint(ByVal e作为PaintEventArgs)
    Console.WriteLine(e.ClipRectangle.ToString())
    使用br作为新的SolidBrush(Me.BackColor)
    e、 Graphics.FillRectangle(br,Me.ClientRectangle)
    终端使用
    如果mImage不是什么,那么
    e、 Graphics.DrawImage(模拟图像,0,0)
    如果结束
    MyBase.OnPaint(e)
    端接头
    _
    私有共享函数LockWindowUpdate(ByVal hWnd作为IntPtr)作为布尔值
    端函数
    末级
    
    与VisualBasic的普通面板类似,它继承面板的所有属性,除非您通过编程来执行所需的操作。请注意,您必须在控制栏中显示为一个名为“MyPanel”的控件,然后将其重命名为所需的控件。要显示为控制状态,必须构建解决方案


    你打开表单,瞧,你使用它。

    有效的解决方案是创建一个自定义面板(一个从控制面板继承的类),并在生成必要的代码以锁定重画时,使用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
    
    公共类MyPanel
    继承面板
    公共分新()
    Me.AutoScroll=True
    Me.SetStyle(ControlStyles.SupportsTransparentBackColor,True)
    Me.SetStyle(ControlStyles.OptimizedDoubleBuffer,True)
    端接头
    私有镜像作为镜像
    公共属性图像()作为图像
    得到
    返回图像
    结束
    设置(ByVal值作为图像)
    图像=值
    使无效
    端集
    端属性
    受保护的覆盖子OnScroll(ByVal se作为ScrollEventArgs)
    如果se.Type=ScrollEventType.First,则
    LockWindowUpdate(Me.Handle)
    ElseIf se.Type=ScrollEventType.ThumbTrack或Else se.Type=ScrollEventType.ThumbPosition然后
    锁窗口更新(IntPtr.Zero)
    我
    LockWindowUpdate(Me.Handle)
    其他的
    锁窗口更新(IntPtr.Zero)
    使无效
    如果结束
    MyBase.OnScroll(东南)
    端接头
    受保护的覆盖子OnPaint(ByVal e作为PaintEventArgs)
    Console.WriteLine(e.ClipRectangle.ToString())
    使用br作为新的SolidBrush(Me.BackColor)
    e、 Graphics.FillRectangle(br,Me.ClientRectangle)
    终端使用
    如果mImage不是什么,那么
    e、 Graphics.DrawImage(模拟图像,0,0)
    如果结束
    我的基地