VB.net透明控件问题
我已经创建了一个如上所述的控件,该控件允许我导入带有alpha通道和随机形状的png。然后,它可以显示在任何其他控件的顶部,即文本框、图片框等。背景应始终显示它下面的内容,而不是仅显示其父控件 如果是静态模式(静止不动)。VB.net透明控件问题,vb.net,gdi,transparent-control,Vb.net,Gdi,Transparent Control,我已经创建了一个如上所述的控件,该控件允许我导入带有alpha通道和随机形状的png。然后,它可以显示在任何其他控件的顶部,即文本框、图片框等。背景应始终显示它下面的内容,而不是仅显示其父控件 如果是静态模式(静止不动)。 但是,当我尝试拖动/移动它时,该控件无法正确地呈现自身,并且还位于其他控件的下方 移动背景时,背景不再正确。控件不知道它,您必须通过调用其Invalidate()方法来告诉它 这是一个Z阶问题。如果表单包含任何嵌套的容器控件,如面板、用户控件或GroupBox,则很难修复此问
但是,当我尝试拖动/移动它时,该控件无法正确地呈现自身,并且还位于其他控件的下方 移动背景时,背景不再正确。控件不知道它,您必须通过调用其Invalidate()方法来告诉它 这是一个Z阶问题。如果表单包含任何嵌套的容器控件,如面板、用户控件或GroupBox,则很难修复此问题。你不能把它显示在上面。但只要所有内容都将窗体作为其父级,那么对控件调用BringToFront()将确保它始终位于顶部 一种更通用的解决方案是一种表单,它覆盖原始表单,并将其“TransparencyKey”属性设置为其背景色,以使其完全透明。您在该窗体上放置的任何控件都将始终位于顶部。我在中的代码演示了覆盖的思想
如果您正在创建自己的设计器,您将需要阅读。是的,表单覆盖是一个分层窗口。是的,实际上我已经完成了覆盖解决方案,我再次这样做的原因是,我将覆盖的表单用作触摸屏键盘界面(如iPhone和其他触摸屏手机的键盘)上的一个高亮度键这会导致SendKey出现问题。SendKey在开始移动控件之前,不需要覆盖。这应该能解决关键问题。
Public Class HighlightKey
Inherits Control
Private m_fillColor As Color = Color.White
Private m_opacity As Integer = 100
Private alpha As Integer
Private m_image As Image
Public Sub New()
SetStyle(ControlStyles.SupportsTransparentBackColor, True)
SetStyle(ControlStyles.Opaque, True)
Me.BackColor = Color.Transparent
Console.WriteLine("new Highlight key ")
End Sub
Public Property Image() As Image
Get
Return m_image
End Get
Set(ByVal value As Image)
m_image = value
End Set
End Property
Protected Overloads Overrides ReadOnly Property CreateParams() As CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or &H20
Return cp
End Get
End Property
Protected Overloads Overrides Sub OnBackColorChanged(ByVal e As EventArgs)
If Me.Parent IsNot Nothing Then
Parent.Invalidate(Me.Bounds, True)
End If
MyBase.OnBackColorChanged(e)
End Sub
Protected Overloads Overrides Sub OnParentBackColorChanged(ByVal e As EventArgs)
Me.Invalidate()
MyBase.OnParentBackColorChanged(e)
End Sub
Protected Overrides Sub OnPaintBackground(ByVal pevent As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaintBackground(pevent)
End Sub
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
Dim g As Graphics = e.Graphics
Dim brush As New SolidBrush(Me.ForeColor)
Dim StringSize As New SizeF
alpha = (m_opacity * 255) / 100
If m_image IsNot Nothing Then
StringSize = g.MeasureString(Me.Text, Me.Font)
Dim x As Integer = (CInt(Me.m_image.Width) - CInt(StringSize.Width)) / 2
g.DrawImage(m_image, 0, 0, m_image.Width, m_image.Height)
g.DrawString(Me.Text, Me.Font, brush, x, 20)
End If
brush.Dispose()
g.Dispose()
MyBase.OnPaint(e)
End Sub
Public Function SetImgOpacity(ByVal imgPic As Image, ByVal imgOpac As Single) As Image
Dim bmpPic As New Bitmap(imgPic.Width, imgPic.Height)
Dim gfxPic As Graphics = Graphics.FromImage(bmpPic)
Dim cmxPic As New ColorMatrix()
cmxPic.Matrix33 = imgOpac
Dim iaPic As New ImageAttributes()
iaPic.SetColorMatrix(cmxPic, ColorMatrixFlag.[Default], ColorAdjustType.Bitmap)
gfxPic.DrawImage(imgPic, New Rectangle(0, 0, bmpPic.Width, bmpPic.Height), 0, 0, imgPic.Width, imgPic.Height, _
GraphicsUnit.Pixel, iaPic)
gfxPic.Dispose()
Return bmpPic
End Function
Private Sub HighlightKey_LocationChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LocationChanged
Me.Refresh()
End Sub
Private Sub HighlightKey_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.TextChanged
Me.Refresh()
End Sub
End Class