【发布时间】:2014-11-20 23:01:48
【问题描述】:
我正在尝试在 PictureBox 控件的顶部放置一个自定义用户控件,但我终其一生都不知道如何设置用户控件的透明度,这样它就不会切掉 PictureBox 图像。
我的用户控件由中间带有文本的 RectangleShape 组成,用于在图像顶部创建一个“徽章”图标(见下图)。 PictureBox 和 User Control 都位于 Panel 控件中,我设置了 PictureBox.SendToBack() 属性和 UserControl.BringToFront() 属性。
我剩下的是:
我的代码如下所示:
Option Explicit On
Option Strict On
Imports Microsoft.VisualBasic.PowerPacks
Public Class BadgeIcon
Inherits UserControl
Private _value As Integer
Private canvas As New ShapeContainer
Private Badge_Icon As New RectangleShape
Private rect As New Rectangle
Private m_BorderColor As Color = Color.White
Private m_FillColor As Color = Color.Red
Private m_BorderThickness As Integer = 2
Private m_BadgeFont As New Font("Segoe UI", 7, FontStyle.Bold)
Private m_BadgeText As String
Private m_TextColor As New SolidBrush(Color.White)
Private m_TextSize As Size
Private m_TextPadding As Integer = 5
Public Property Value() As Integer
Get
Return _value
End Get
Set(value As Integer)
_value = value
m_BadgeText = CStr(_value)
m_TextSize = TextRenderer.MeasureText(m_BadgeText, m_BadgeFont)
rect.Width = m_TextSize.Width + m_TextPadding
rect.Height = m_TextSize.Height + m_TextPadding
Me.Refresh()
End Set
End Property
Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = &H20
Return cp
End Get
End Property
Sub New()
' This call is required by the designer.
InitializeComponent()
SetStyle(ControlStyles.SupportsTransparentBackColor, True)
SetStyle(ControlStyles.Opaque, False)
SetStyle(ControlStyles.DoubleBuffer, True)
SetStyle(ControlStyles.AllPaintingInWmPaint, True)
SetStyle(ControlStyles.UserPaint, True)
Me.BackColor = Color.FromArgb(0, 0, 0, 0)
UpdateStyles()
' Add any initialization after the InitializeComponent() call.
canvas.Parent = Me
Badge_Icon.Parent = canvas
canvas.BackColor = Color.FromArgb(0, 0, 0, 0)
'Create Badge Icon
With Badge_Icon
.BackColor = Color.FromArgb(0, 0, 0, 0)
.BorderColor = m_BorderColor
.BorderWidth = m_BorderThickness
.BorderStyle = Drawing2D.DashStyle.Solid
.CornerRadius = 11
.FillColor = m_FillColor
.FillStyle = FillStyle.Solid
.SelectionColor = Color.Transparent
End With
AddHandler Badge_Icon.Paint, AddressOf BadgeIcon_Paint
End Sub
Protected Overrides Sub OnPaint(e As PaintEventArgs)
MyBase.OnPaint(e)
DrawBadgeIcon(e)
End Sub
Public Sub DrawBadgeIcon(e As PaintEventArgs)
Try
'Alter the size of the icon to fix the text
With Badge_Icon
.Location = New Point(rect.Left + 1, rect.Top + 1)
.Size = New Size(rect.Width, rect.Height - 1)
End With
Catch ex As Exception
ErrorTrap(ex, "cls_NotificationBadgeIcon: DrawBadgeIcon()")
End Try
End Sub
Private Sub BadgeIcon_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs)
Dim textRect As New Rectangle(2, 2, m_TextSize.Width + m_TextPadding - 1, m_TextSize.Height + m_TextPadding - 2)
'Draw the Text
Dim flags As New StringFormat
flags.Alignment = StringAlignment.Center
flags.LineAlignment = StringAlignment.Center
e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
e.Graphics.DrawString(m_BadgeText, m_BadgeFont, m_TextColor, textRect, flags)
End Sub
End Class
然后将所有内容添加到我的主表单中,我调用以下内容:
Dim pic As New PictureBox
pic.Image = My.Resources.Notifications
pic.SizeMode = PictureBoxSizeMode.StretchImage
pic.Location = New Point(21, 221)
pic.Size = New Size(42, 29)
pnlLeftMenuBar.Controls.Add(pic)
pic.SendToBack()
Dim Counter_Notify As New BadgeIcon
Counter_Notify.Location = New Point(50, 240)
pnlLeftMenuBar.Controls.Add(Counter_Notify)
Counter_Notify.BringToFront()
并且只需使用Counter_Notify.Value = 1 来更新计数器值。
如何删除切掉背景图像的方形矩形?还是我应该以完全不同的方式进行设置?我对用户控件有点陌生。
任何帮助表示赞赏。谢谢
【问题讨论】:
-
透明背景并不代表你认为的那样。对于透明背景,Net/Windows 使用父背景色。由于您的 UC 的父级是面板,这就是要绘制的内容。当您在带有不同内容的表单上拖动标签时,您可以看到它发生了变化。您可以将徽章/叠加层绘制到要修改的图像上,而不是堆叠控件。
-
@Plutonix 好吧...我确实将图像直接绘制到面板中,这确实给了我所需的结果,但是,我无法将任何事件处理程序附加到图像(例如工具提示和点击事件),所以我选择了一个图片框。那么这个问题还有什么办法吗?
-
在图像上绘制叠加层,将图像发布到面板或 picbox 并使用控件的事件进行点击
-
@Plutonix 那么您是不是建议根本不使用用户控件?只需创建一个 PictureBox 控件,添加图像,然后在顶部绘制 RectangleShape?
-
成功了,你看到了面板的背景。因为您已将其添加到面板中,所以将其添加到 pic 中。也不需要特殊代码,只需将 BackColor 设置为 Color.Transparent。是的,只是在 pic.Paint 事件的事件处理程序中绘制它会更有效。
标签: vb.net user-controls transparency picturebox