مقدمة
الهدف من هذا المقال هو أن نتعلم معا كيفية بناء كونترول يدعم خاصية الشفافية وذلك عن طريق الوراثة. في واقع الأمر وكما يعلم الجميع فإن الفورم فقط هو الذي يدعم خاصية الشفافية وذلك من خلال التحكم في قيمة Opacity Property ولسوف تسخدم نفس الإستراتيجية الموجودة في الفورم لكي نصنع كونترول شفاف
طبقا لشركة مايكروسوفت فإن الكونترل كلاس يمتلك بعض الإجراءات التي لو استخدمت بشكل صحيح فسستطيع ان نحقق الشقاقية مع الكونترول وهذه الاجراءات مصنفة كالتالي
- SetStyle Method وهذا الإجراء يسمح لنا بالتعامل مع ControlStyles Enum وتحديد قيمتها
- GetStyle Method وهذا الإجراء يسمح لنا باسترجاع االقيمة التي تم تحديدها مع ControStyles Enum
- UpdateStyles Method هذا الإجراء يقوم بإجبار الإجراء CreateParams علي التعديل في قيم Styel و قيم ExStyle حيث هذا يعطينا ميزة التحكم في في سلوك الكونترول
ولمزيد من التفاصيل عن هذه الإجراءات يمكنك البحث في MSDN
بناء الكونترول
الخطوات التالية توضح كيفية بناء الكونترول الشفاف
نفتح مشروع جديد ونضيف للمشروع كلاسا لنطلق عليه TransparentControl
ومن ثم وباستخدام الوراثة نضيف كونترول الي هذا الكلاس
Public Class TransparentControl
Inherits Control
End Class
في الإجراء New نقوم بتحديد القيم الخاصة بالإجراء SetStyle ومن خلالها نحدد قيمة ControlStyles Enum فيكون لدينا الكود بالشكل التالي
Public Sub New()
SetStyle(ControlStyles.SupportsTransparentBackColor, True)
SetStyle(ControlStyles.Opaque, False)
SetStyle(ControlStyles.DoubleBuffer, True)
SetStyle(ControlStyles.AllPaintingInWmPaint, True)
SetStyle(ControlStyles.UserPaint, True)
UpdateStyles()
' ......... rest of the code
End Sub
#End Region
#Region " Constructor "
الأن نقوم بعمل Overrides للصفة BackColor ونجعل قيمتها تعادل Color.Transparent ثم وبإستخدام Attributes نقوم بإخفائها والكود التالي يوضح ذلك
<System.ComponentModel.Browsable(False)> _
<System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)> _
<System.ComponentModel.DefaultValue(GetType(Color), "Transparent")> _
<System.ComponentModel.Description("Set background color.")> _
<System.ComponentModel.Category("Control Style")> _
Public Overrides Property BackColor() As System.Drawing.Color
Get
Return m_backcolor
End Get
Set(ByVal value As System.Drawing.Color)
m_backcolor = value
Refresh()
End Set
End Property
الأن نقوم بإضافة Opacity Property ويجب أن نلاحظ أن هناك كلاسا موجود في الدوت نت وهذا الكلاس اسمه OpacityConverter وهذا الكلاس عبارة عن Editor ويتم استخدامه في Attributes لكي يقوم بتحويل القيم من والي String ومن داخل Opacity Property يجب أن نستخدم الإجراء UpdateStyle لكي نجبر الكونترول علي تغيير قيمة Style وذلك عندما تتغير قيمة Opacity
<System.ComponentModel.Browsable(True)> _
<System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Always)> _
<System.ComponentModel.DefaultValue(1.0R)> _
<System.ComponentModel.TypeConverter(GetType(OpacityConverter))> _
<System.ComponentModel.Description("Set the opacity percentage of the control.")> _
<System.ComponentModel.Category("Control Style")> _
Public Overridable Property Opacity() As Double
Get
Return m_opacity
End Get
Set(ByVal value As Double)
If value = m_opacity Then
Return
End If
m_opacity = value
UpdateStyles()
Refresh()
End Set
End Property
الأن نضيف صفة أخري وهي Transparent وهذه الخاصية عبارة عن Boolean وعندما تكون قيمتها False فإن الكونترول لن يكون شفافا
<System.ComponentModel.Browsable(True)> _
<System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Always)> _
<System.ComponentModel.DefaultValue(GetType(Boolean), "False")> _
<System.ComponentModel.Description("Enable control trnasparency.")> _
<System.ComponentModel.Category("Control Style")> _
Public Overridable Property Transparent() As Boolean
Get
Return m_transparent
End Get
Set(ByVal value As Boolean)
If value = m_transparent Then
Return
End If
m_transparent = value
Refresh()
End Set
End Property
الأن لنضيف صفة أخري للكونترول وهي TransparentColor Property وهي سوف تستخدم لتحديد اللون المستخدم في رسم الكونترول
<System.ComponentModel.Browsable(True)> _
<System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Always)> _
<System.ComponentModel.DefaultValue(GetType(Color), "DodgerBlue")> _
<System.ComponentModel.Description("Set the fill color of the control.")> _
<System.ComponentModel.Category("Control Style")> _
Public Overridable Property TransparentColor() As Color
Get
Return m_transparentColor
End Get
Set(ByVal value As Color)
m_transparentColor = value
Refresh()
End Set
End Property
الأن وبعد أن إنتهينا من إضافة بعض Property الي الكونترول يجب علينا أن نقوم بعملية الرسم
كيف نرسم الشفافية
الكود التالي يوضح كيفية رسم الكونترول الشفاف ومن ثم نقوم بتمرير هذا الكود الي OnPaint Event لكي نحصل علي الكونترول الشفاف
Public Overridable Sub DrawBackground(ByVal g As Graphics, ByVal control As TransparentControl)
If Transparent Then
Using sb As New SolidBrush(control.BackColor)
g.FillRectangle(sb, control.ClientRectangle)
sb.Dispose()
Using sbt As New SolidBrush(Color.FromArgb(control.Opacity * 255, control.TransparentColor))
g.FillRectangle(sbt, control.ClientRectangle)
sbt.Dispose()
End Using
End Using
Else
Using sb As New SolidBrush(control.TransparentColor)
g.FillRectangle(sb, control.ClientRectangle)
sb.Dispose()
End Using
End If
End Sub
ويمكننا أنرسم اي شئ أخر نريده مثل Border علي سبيل المثال والكود التالي يوضح ذلك
Using p As New Pen(GetDarkColor(Me.TransparentColor, 40), 1)
Dim rect As New Rectangle(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - 1, ClientRectangle.Height - 1)
rect.Inflate(-1, -1)
g.DrawRectangle(p, rect)
p.Dispose()
End Using
End Sub
Public Overridable Sub DrawBorder(ByVal g As Graphics, ByVal control As TransparentControl)
بالتأكيد نستطيع أن نفعل الكثير ونرسم الكثير باستخدام نفس الاستراتيجية فقط علينا أن نمرر ما نرسم الي OnPaint Event
عموما وفي المرفقات ستجدون نسخة كاملة من الكود بنسخة الفيجوال استوديو 2008
ملحوظة
الكونترول أيضا يدعم تكنولوجيا Smart Tags وهناك مقال كنت فد كتبته منذ فترة طويلة هنا بالموقع عن كيفية إضافة smart tags الي الكونترول أعتقد يمكنم البحث بالموقع وقراءته
مع تحياتي للجميع
أخوكم عمر