تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
مقال- أفكار في الدوت نت Enum
#1
كاتب الموضوع : silverlight

بسم الله الرحمن الرحيم


السلام عليكم ورحمة الله وبركاته

مقدمـــــة:

من المؤكد أن قارئ هذا المقال فد سمع عن أو استخدم كلمة Enum من قبل في برامجه وتقريبا جميع NameSpaces الموجودة في الدوت نت يوجد بها Enum وأيضا قلما ما يخلو أي مشروع في الدوت نت من Enum .
وفي موضوعنا هذا سوف نركز علي كيفية الإستفادة من Enums الموجودة بالدوت نت.

ماهي Enum :

كلمة Enum هي إختصار متعارف عليه لكلمة Enumerations وهي عبارة عن ثوابت يتم تعريفها بواسطة المبرمج ومن ثم يستفيد بها بشكل ما من داخل برامجه وكلمة Enumerations تعادل كلمة التعدادات في اللغة العربية وهذا مجرد ترجمة حرفية ليس إلا ولكن التعريف الحقيقي لهذه الكلمة هو أن Enumerations عبارة عن ثوابت او متغيرات يتم وضعها معا في مجموعة ويطلق عليها إسم ما والكود التالي يوضح كيفية تعريف Enumerations


كود :
Public Enum Direction
Left
Right
Up
Down
End Enum
أيضا علي سبيل المثال لا الحصر فضاء الأسماء التالية يوجد بها عدد لا بأس به من Enumerations

System.Drawing Namespace
يوجد بها ContentAlignment , KnownColor, StringAlignment و غيرهم الكثير

System.Drawing.Drawing2D Namespace يوجد بها HatchStyle, SmoothingMode, DashCap و غيرهم الكثير

System.Windows.Forms Namespace يوجد بها AnchorStyles, BorderStyle, ButtonState وغيرهم الكثير

عموما جميع الأمثلة أعلاه تؤكد شئ واحد فقط أنه لايمكن بأي حال من الأحوال الإستغناء عن Enums


كيف نستفيد من Enum :

الأمثلة التالية توضح كيفية الإستفادة من Enum في برامجنا
ولكي نستفيد أكثر من الأمثلة التي سوف نعطيها سأحاول أن أبني بعض الكونترول التي من الممكن أن نستفيد منها بشكل أكثر فعالية

المثال الأول:


فضاء الأسماء System.Drawing Namespace يوجد بها Enumerations التالية

ContentAlignment
StringAlignment

الكود التالي يوضح كيفية الإستفادة من كل منهما في بناء كونترول بسيط جدا مثل Label Control ولكنه شفاف ....... ويمكن استخدامه بسهولة ...... في برامجكم
عموما لن أناقش الكود الخاص بهذا الكونترول بشكل كامل ولكن ما يهمني هنا هو أن تلاحظوا كيف تم الاستفادة من Enum في تغيير شكل الكونترول عن طريق الإستفادة من الثوابت الموجودة في كل من ContentAlignment Eum و أيضا StringAlignment Enum والجزء التالي من الكود يوضح الأمر


كود :
If Me.Text IsNot Nothing Then
Dim format As New StringFormat()
format.LineAlignment = StringAlignment.Center
format.Trimming = StringTrimming.EllipsisCharacter
Select Case Me._textAlign
Case ContentAlignment.BottomCenter
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Far
Exit Select
Case ContentAlignment.BottomLeft
format.Alignment = StringAlignment.Near
format.LineAlignment = StringAlignment.Far
Exit Select
Case ContentAlignment.BottomRight
format.Alignment = StringAlignment.Far
format.LineAlignment = StringAlignment.Far
Exit Select
Case ContentAlignment.MiddleCenter
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Center
Exit Select
Case ContentAlignment.MiddleLeft
format.Alignment = StringAlignment.Near
format.LineAlignment = StringAlignment.Center
Exit Select
Case ContentAlignment.MiddleRight
format.Alignment = StringAlignment.Far
format.LineAlignment = StringAlignment.Center
Exit Select
Case ContentAlignment.TopCenter
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Near
Exit Select
Case ContentAlignment.TopLeft
format.Alignment = StringAlignment.Near
format.LineAlignment = StringAlignment.Near
Exit Select
Case ContentAlignment.TopRight
format.Alignment = StringAlignment.Far
format.LineAlignment = StringAlignment.Near
Exit Select
End Select

Using textBrush As New SolidBrush(MyBase.ForeColor)
e.Graphics.DrawString(MyBase.Text, MyBase.Font, textBrush, borderRect, format)
End Using

End If
أيضا الكود التالي يوضح كيفية تحديد مكان المستطيل الذي يتم من خلاله رسم صورة علي الكونترول وذلك عند تغير القيم الخاصة بالمتغيرات الموجودة داخل Enum ContentAlignment


كود :
Private Function GetImageRectangle(ByVal img As Image, ByVal rect As Rectangle, ByVal align As ContentAlignment) As Rectangle

Dim imageSize As Size = img.Size
Dim x As Integer = (rect.X + 2)
Dim y As Integer = (rect.Y + 2)

If ((align And (ContentAlignment.BottomRight Or (ContentAlignment.MiddleRight Or ContentAlignment.TopRight))) <> DirectCast(0, ContentAlignment)) Then
x = (((rect.X + rect.Width) - 4) - imageSize.Width)
ElseIf ((align And (ContentAlignment.BottomCenter Or (ContentAlignment.MiddleCenter Or ContentAlignment.TopCenter))) <> DirectCast(0, ContentAlignment)) Then
x = (rect.X + ((rect.Width - imageSize.Width) / 2))
End If

If ((align And (ContentAlignment.BottomRight Or (ContentAlignment.BottomCenter Or ContentAlignment.BottomLeft))) <> DirectCast(0, ContentAlignment)) Then
y = (((rect.Y + rect.Height) - 4) - imageSize.Height)
ElseIf ((align And (ContentAlignment.TopRight Or (ContentAlignment.TopCenter Or ContentAlignment.TopLeft))) <> DirectCast(0, ContentAlignment)) Then
y = (rect.Y + 2)
Else
y = (rect.Y + ((rect.Height - imageSize.Height) / 2))
End If

Return New Rectangle(x, y, imageSize.Width, imageSize.Height)

End Function
في المرفقات ستجدون نسخة كاملة من الكود ..........................
الأكواد الموجودة بالمثال الأول يمكن الإستفادة منها أيضا في تطوير الكود الموجود في المقال الموجود تحت اللينك التالي ..........

كود : باتون شفاف

ملاحظات هامة :

الكود الموجود بالمرفقات بنسخة الفيجوال استوديو 2010
وفي المشاركة التالية سوف أضع الكود كاملا الخاص بالكونترول لكي يستفيد منه من لا يملكون نسخة الفيجوال 2010

أيضا في المشاركات اللاحقة سوف نناقش كيف نستفيد أكثر من Enum و بطرق أخري مختلفة ............

تقبلوا تحياتي ولا تنسونا في دعائكم..............

أخوكم عمر


الملفات المرفقة
.rar   Enums_example1_src.rar (الحجم : 129.29 ك ب / التحميلات : 38)
}}}}
تم الشكر بواسطة:
#2
الكود الخاص بالكونترول TransparentLabel والموجود بالمثال رقم 1 في المشاركة السابقة لكي يستفيد منه من لا يملكون نسخة الفيجوال 2010

فقط عليكم كتابة الكود في اي من مشروعتكم ثم عمل Build للكونترول ومن ثم ستجدون منه نسخة في صندوق الأدوات ويمكنكم التعامل معه مثلما تتعاملون مع أي كونترول أخر

يتم التحكم في شفافية الكونترول من خلال Opacity Property


كود :
Imports System.Windows.Forms
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.ComponentModel

Public Class TransparentLabel
Inherits Control

#Region " Fields "

Private _opacity As Double = 1.0
Private _imageAlighn As ContentAlignment = ContentAlignment.MiddleCenter
Private _textAlign As ContentAlignment = ContentAlignment.TopLeft
Private _image As Image = Nothing

#End Region

#Region " Constructor "

Public Sub New()
MyBase.SetStyle(ControlStyles.SupportsTransparentBackColor, True)
MyBase.SetStyle(ControlStyles.Opaque, False)
MyBase.SetStyle(ControlStyles.DoubleBuffer, True)
MyBase.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
MyBase.SetStyle(ControlStyles.UserPaint, True)
MyBase.SetStyle(ControlStyles.ResizeRedraw, True)
MyBase.UpdateStyles()
End Sub

#End Region

#Region " Properties "

<Browsable(True)> _
<EditorBrowsable(System.ComponentModel.EditorBrowsableState.Always)> _
<DefaultValue(GetType(Double), "1")> _
<TypeConverter(GetType(OpacityConverter))> _
<Description("Set the opacity percentage of the control.")> _
<Category("Aero")> _
Public Property Opacity() As Double
Get
Return Me._opacity
End Get
Set(ByVal value As Double)
If value = Me._opacity Then
Return
End If
Me._opacity = value
Me.UpdateStyles()
Me.Invalidate()
End Set
End Property

<Browsable(True)> _
<EditorBrowsable(EditorBrowsableState.Always)> _
<DefaultValue(GetType(ContentAlignment), "MiddleCenter")> _
<Description("Set the position of image within the control.")> _
<Category("Aero")> _
Public Property ImageAlign As ContentAlignment
Get
Return Me._imageAlighn
End Get
Set(ByVal value As ContentAlignment)
Me._imageAlighn = value
Invalidate()
End Set
End Property

<Browsable(True)> _
<EditorBrowsable(EditorBrowsableState.Always)> _
<DefaultValue(GetType(ContentAlignment), "TopLeft")> _
<Description("Set the position of text within the control.")> _
<Category("Aero")> _
Public Property TextAlign As ContentAlignment
Get
Return Me._textAlign
End Get
Set(ByVal value As ContentAlignment)
Me._textAlign = value
Invalidate()
End Set
End Property

<Browsable(True)> _
<EditorBrowsable(EditorBrowsableState.Always)> _
<Description("Set the image of the control.")> _
<Category("Aero")> _
Public Property Image As Image
Get
Return Me._image
End Get
Set(ByVal value As Image)
Me._image = value
Invalidate()
End Set
End Property

Public Overloads Property ForeColor As Color
Get
Return MyBase.ForeColor
End Get
Set(ByVal value As Color)
MyBase.ForeColor = value
Invalidate()
End Set
End Property

<Browsable(True), EditorBrowsable(EditorBrowsableState.Always), Localizable(True)> _
Public Overrides Property Text As String
Get
Return MyBase.Text
End Get
Set(ByVal value As String)
MyBase.Text = value
Invalidate()
End Set
End Property

#End Region

#Region " Methods "

Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
InvokePaintBackground(Me, e)
Dim rect As Rectangle = MyBase.ClientRectangle
Using sb As New SolidBrush(Color.FromArgb(Me.BackColor.A * Me.Opacity, Me.BackColor))
e.Graphics.FillRectangle(sb, Me.ClientRectangle)
rect.Width -= 1
rect.Height -= 1
e.Graphics.DrawRectangle(New Pen(sb), rect)
End Using

Dim borderRect As Rectangle = MyBase.ClientRectangle
borderRect.Width -= 1
borderRect.Height -= 1

If Me.Image IsNot Nothing Then
Me.DrawImage(e.Graphics, Image, borderRect, MyBase.RtlTranslateAlignment(Me.ImageAlign))
End If

If Me.Text IsNot Nothing Then
Dim format As New StringFormat()
format.LineAlignment = StringAlignment.Center
format.Trimming = StringTrimming.EllipsisCharacter
Select Case Me._textAlign
Case ContentAlignment.BottomCenter
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Far
Exit Select
Case ContentAlignment.BottomLeft
format.Alignment = StringAlignment.Near
format.LineAlignment = StringAlignment.Far
Exit Select
Case ContentAlignment.BottomRight
format.Alignment = StringAlignment.Far
format.LineAlignment = StringAlignment.Far
Exit Select
Case ContentAlignment.MiddleCenter
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Center
Exit Select
Case ContentAlignment.MiddleLeft
format.Alignment = StringAlignment.Near
format.LineAlignment = StringAlignment.Center
Exit Select
Case ContentAlignment.MiddleRight
format.Alignment = StringAlignment.Far
format.LineAlignment = StringAlignment.Center
Exit Select
Case ContentAlignment.TopCenter
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Near
Exit Select
Case ContentAlignment.TopLeft
format.Alignment = StringAlignment.Near
format.LineAlignment = StringAlignment.Near
Exit Select
Case ContentAlignment.TopRight
format.Alignment = StringAlignment.Far
format.LineAlignment = StringAlignment.Near
Exit Select
End Select

Using textBrush As New SolidBrush(MyBase.ForeColor)
e.Graphics.DrawString(MyBase.Text, MyBase.Font, textBrush, borderRect, format)
End Using

End If

End Sub

Protected Overrides Sub OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs)
Dim grContainer As GraphicsContainer = e.Graphics.BeginContainer()
e.Graphics.TranslateTransform(-Me.Left, -Me.Top)
Using pe As PaintEventArgs = New PaintEventArgs(e.Graphics, e.ClipRectangle)
InvokePaintBackground(Me.Parent, pe)
InvokePaint(Me.Parent, pe)
End Using
e.Graphics.ResetTransform()
e.Graphics.EndContainer(grContainer)
End Sub

Protected Overrides Sub OnMove(ByVal e As System.EventArgs)
MyBase.OnMove(e)
Me.Invalidate()
End Sub

Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
MyBase.OnResize(e)
Me.Invalidate()
End Sub

Private Function GetImageRectangle(ByVal img As Image, ByVal rect As Rectangle, ByVal align As ContentAlignment) As Rectangle

Dim imageSize As Size = img.Size
Dim x As Integer = (rect.X + 2)
Dim y As Integer = (rect.Y + 2)

If ((align And (ContentAlignment.BottomRight Or (ContentAlignment.MiddleRight Or ContentAlignment.TopRight))) <> DirectCast(0, ContentAlignment)) Then
x = (((rect.X + rect.Width) - 4) - imageSize.Width)
ElseIf ((align And (ContentAlignment.BottomCenter Or (ContentAlignment.MiddleCenter Or ContentAlignment.TopCenter))) <> DirectCast(0, ContentAlignment)) Then
x = (rect.X + ((rect.Width - imageSize.Width) / 2))
End If

If ((align And (ContentAlignment.BottomRight Or (ContentAlignment.BottomCenter Or ContentAlignment.BottomLeft))) <> DirectCast(0, ContentAlignment)) Then
y = (((rect.Y + rect.Height) - 4) - imageSize.Height)
ElseIf ((align And (ContentAlignment.TopRight Or (ContentAlignment.TopCenter Or ContentAlignment.TopLeft))) <> DirectCast(0, ContentAlignment)) Then
y = (rect.Y + 2)
Else
y = (rect.Y + ((rect.Height - imageSize.Height) / 2))
End If

Return New Rectangle(x, y, imageSize.Width, imageSize.Height)

End Function

Private Sub DrawImage(ByVal g As Graphics, ByVal img As Image, ByVal imageRect As Rectangle, ByVal align As ContentAlignment)
Dim r As Rectangle = Me.GetImageRectangle(img, imageRect, align)
g.DrawImage(img, r.X, r.Y, img.Width, img.Height)
End Sub

#End Region

End Class ' TransparentLabel

تقبلوا تحياتي ولا تنسونا في دعائكم..............

أخوكم عمر
}}}}
تم الشكر بواسطة:
#3
المثال الثاني:

من المؤكد أن الكثير من االمبرمجين يعلمون كيفية صناعة كونترول يتم توريثه من ListBox أو ComboBox ومن ثم نضيف له الألوان المختلفة ولو بحثتم جيدا في الموقع أو علي النت بشكل عام ستجدون أفكارا كثيرة تتحدث عن هذا الأمر. عموما المثال التالي سيوضح نفس الأمر ولكن باستخدام Enum وبأسلوب مغاير للطرق المعتادة.

في الدوت نت يوجد Enum إسمه KnownColor و الكود التالي يوضح كيفية إضافته الي ComboBox واستخدامه في الحصول علي لون معين

وتتلخص الفكرة و بإختصار شديد في أننا نقوم بتعريف متغير عبارة عن Type ومن ثم نستخدم GetType ونمرر لها Enum ومن ثم نستخدم جملة For.....Each لكي نضيف المتغيرات الموجودة في أي Enum الي ComboBox وذلك باستخدام Enum.GetValues والكود التالي يوضح الفكرة و لكي تقوم بتنفيذ الكود افتح مشروع وأضف الي الفورم .... كومبوبوكس كونترول ثم اكتب الكود بالشكل التالي


كود :
Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim KnonColorEnumType As Type = GetType(KnownColor)
For Each knownColorObject As Object In [Enum].GetValues(KnonColorEnumType)
If Not ComboBox1.Items.Contains(knownColorObject) Then ComboBox1.Items.Add(knownColorObject)
Next

End Sub

End Class
ويمكن إعادة كتابة الكود أعلاه بالشكل التالي ولكن مع استخدام ListBox بدلا من ComboBox
وستلاحظون هنا كيفية تمرير القيمة مباشرة بدون تعريف متغير يعبر عن Type كما بالكود أعلاه


كود :
Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For Each knownColorObject As Object In [Enum].GetValues(GetType(KnownColor))
If Not ListBox1.Items.Contains(knownColorObject) Then ListBox1.Items.Add(knownColorObject)
Next
End Sub

End Class
الأن وبعد أن تم إضافة القيم التي تخص KnownColor Enum يتبقي كيفية استرجاع القيمة الخاصة بكل عنصر أو كل متغير داخل Enum لذلك يمكننا أن نبني دالة بسيطة جدا لتحويل كلString من عناصر KnowColor Enum الي KnownColor ويتم ذلك باستخدام Enum.Prase والكود التالي يوضح شكل الدالة


كود :
Private Function GetKnowColorString(ByVal ColorName As String, ByVal ignoreCase As Boolean) As KnownColor
Return CType([Enum].Parse(GetType(Drawing.KnownColor), ColorName, ignoreCase), Drawing.KnownColor)
End Function
ومن ثم في الحدث SelectedIndexChanged يتم استرجاع اللون واستخدامه كيفما شئنا
والكود التالي يوضح كيفية استرجاع اللون ومن ثم تغيير خلفية االفورم


كود :
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
Me.BackColor = Color.FromKnownColor(GetKnowColorString(Me.ComboBox1.SelectedItem, True))
End Sub

Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
Me.BackColor = Color.FromKnownColor(GetKnowColorString(Me.ListBox1.SelectedItem, True))
End Sub
الكود التالي يوضح الشكل النهائي للكود وبالمرفقات ستجدون نسخة من المثال


كود :
Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' Fill ListBox with KnowColor Enum
For Each knownColorObject As Object In [Enum].GetValues(GetType(KnownColor))
If Not ListBox1.Items.Contains(knownColorObject) Then ListBox1.Items.Add(knownColorObject)
Next

' Fill ComboBox with KnowColor Enum
Dim KnonColorEnumType As Type = GetType(KnownColor)
For Each knownColorObject As Object In [Enum].GetValues(KnonColorEnumType)
If Not ComboBox1.Items.Contains(knownColorObject) Then ComboBox1.Items.Add(knownColorObject)
Next
End Sub

Private Function GetKnowColorString(ByVal ColorName As String, ByVal ignoreCase As Boolean) As KnownColor
Return CType([Enum].Parse(GetType(Drawing.KnownColor), ColorName, ignoreCase), Drawing.KnownColor)
End Function

Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
Me.BackColor = Color.FromKnownColor(GetKnowColorString(Me.ComboBox1.SelectedItem, True))
End Sub

Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
Me.BackColor = Color.FromKnownColor(GetKnowColorString(Me.ListBox1.SelectedItem, True))
End Sub

End Class
الكود الموجود بالمرفقات بنسخة الفيجوال استوديو 2010

في المشاركات اللاحقة سوف نناقش كيف نستفيد أكثر من Enum و بطرق أخري مختلفة

تقبلوا تحياتي ولا تنسونا في دعائكم..............

أخوكم عمر


الملفات المرفقة
.rar   Enum_Example2_src.rar (الحجم : 61.28 ك ب / التحميلات : 32)
}}}}
تم الشكر بواسطة:
#4
مثلما فعلنا في المثال الثاني يمكننا ان نضيف أي Enum الي ComboBox أو ListBox
والمثال الثالث مجرد تأكيد لنفس الفكرة المستخدمة مع المثال الثاني ولكن من ُEnum اخر وهو Hatchstyle Enum بالإضافة الي بعض Enums الأخري

والكود التالي يوضح الشكل النهائي للكود ولتنفيذ الكود أضف الي الفورم أربعة كومبوبوكس


كود :
Public Class Form1

Private align As ContentAlignment = ContentAlignment.TopLeft
Private clr As Color = Color.Empty
Private hatch As HatchStyle = Nothing
Private pType As DashStyle = DashStyle.Dash

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

' Fill ComboBox1 with HatchStyle Enum
For Each hatchStyleObject As Object In [Enum].GetValues(GetType(HatchStyle))
If Not ComboBox1.Items.Contains(hatchStyleObject) Then ComboBox1.Items.Add(hatchStyleObject)
Next

' Fill ComboBox2 with ContentAlignment Enum
For Each contentAlignmentObject As Object In [Enum].GetValues(GetType(ContentAlignment))
If Not ComboBox2.Items.Contains(contentAlignmentObject) Then ComboBox2.Items.Add(contentAlignmentObject)
Next

' Fill ComboBox3 with KnowColor Enum
For Each knownColorObject As Object In [Enum].GetValues(GetType(KnownColor))
If Not ComboBox3.Items.Contains(knownColorObject) Then ComboBox3.Items.Add(knownColorObject)
Next

' Fill ComboBox4 with DashStyle Enum
For Each dashStyleObject As Object In [Enum].GetValues(GetType(DashStyle))
If Not ComboBox4.Items.Contains(dashStyleObject) Then ComboBox4.Items.Add(dashStyleObject)
Next

End Sub

Private Function GetHatchStyleFromString(ByVal hatchString As String, ByVal ignoreCase As Boolean) As HatchStyle
Return CType([Enum].Parse(GetType(HatchStyle), hatchString, ignoreCase), HatchStyle)
End Function

Private Function GetContentAlinmentFromString(ByVal hatchString As String, ByVal ignoreCase As Boolean) As ContentAlignment
Return CType([Enum].Parse(GetType(ContentAlignment), hatchString, ignoreCase), ContentAlignment)
End Function

Private Function GetKnowColorString(ByVal ColorName As String, ByVal ignoreCase As Boolean) As KnownColor
Return CType([Enum].Parse(GetType(KnownColor), ColorName, ignoreCase), KnownColor)
End Function

Private Function GetDashStyleString(ByVal ColorName As String, ByVal ignoreCase As Boolean) As DashStyle
Return CType([Enum].Parse(GetType(DashStyle), ColorName, ignoreCase), DashStyle)
End Function

' Get HatchStyle value from ComboBox1
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
hatch = GetHatchStyleFromString(Me.ComboBox1.SelectedItem, True)
Invalidate()
End Sub

' Get ContentAlignment value from ComboBox2
Private Sub ComboBox2_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox2.SelectedIndexChanged
align = GetContentAlinmentFromString(Me.ComboBox2.SelectedItem, True)
Invalidate()
End Sub

' Get Color value from ComboBox3
Private Sub ComboBox3_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox3.SelectedIndexChanged
clr = Color.FromKnownColor(GetKnowColorString(Me.ComboBox3.SelectedItem, True))
Invalidate()
End Sub

' Get Pen DashStyle value from ComboBox4
Private Sub ComboBox4_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox4.SelectedIndexChanged
pType = GetDashStyleString(Me.ComboBox4.SelectedItem, True)
Invalidate()
End Sub

' Paint Something in the Form
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)

Dim TestRectangle As New Rectangle(10, 10, 200, 200)
Dim frameRect As Rectangle = TestRectangle
frameRect.X -= 4
frameRect.Y -= 4
frameRect.Width += 8
frameRect.Height += 8

Using obrush As New Drawing2D.LinearGradientBrush(frameRect, ControlPaint.Light(clr), ControlPaint.Dark(clr), Drawing2D.LinearGradientMode.Vertical)
e.Graphics.FillRectangle(obrush, frameRect)
Using framePen As New Pen(Brushes.Black)
framePen.DashStyle = pType
e.Graphics.DrawRectangle(framePen, frameRect)
End Using
End Using

Using hBrush As New Drawing2D.HatchBrush(hatch, clr)
e.Graphics.FillRectangle(hBrush, TestRectangle)
Using borderPen As New Pen(clr)
borderPen.DashStyle = pType
e.Graphics.DrawRectangle(borderPen, TestRectangle)
End Using
End Using

If Me.Text IsNot Nothing Then
Dim format As New StringFormat()
format.LineAlignment = StringAlignment.Center
format.Trimming = StringTrimming.EllipsisCharacter
Select Case align
Case ContentAlignment.BottomCenter
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Far
Exit Select
Case ContentAlignment.BottomLeft
format.Alignment = StringAlignment.Near
format.LineAlignment = StringAlignment.Far
Exit Select
Case ContentAlignment.BottomRight
format.Alignment = StringAlignment.Far
format.LineAlignment = StringAlignment.Far
Exit Select
Case ContentAlignment.MiddleCenter
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Center
Exit Select
Case ContentAlignment.MiddleLeft
format.Alignment = StringAlignment.Near
format.LineAlignment = StringAlignment.Center
Exit Select
Case ContentAlignment.MiddleRight
format.Alignment = StringAlignment.Far
format.LineAlignment = StringAlignment.Center
Exit Select
Case ContentAlignment.TopCenter
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Near
Exit Select
Case ContentAlignment.TopLeft
format.Alignment = StringAlignment.Near
format.LineAlignment = StringAlignment.Near
Exit Select
Case ContentAlignment.TopRight
format.Alignment = StringAlignment.Far
format.LineAlignment = StringAlignment.Near
Exit Select
End Select
Dim fnt As New Font("Times /new Roman", 25.0F, FontStyle.Bold)
Using sb As New SolidBrush(Color.White)
e.Graphics.DrawString(Me.Text, fnt, sb, TestRectangle, format)
End Using
End If

End Sub

End Class
الكود الموجود بالمرفقات بنسخة الفيجوال استوديو 2010

في المشاركات اللاحقة سوف نناقش كيف نستفيد أكثر من Enum و بطرق أخري مختلفة

تقبلوا تحياتي ولا تنسونا في دعائكم..............

أخوكم عمر


الملفات المرفقة
.rar   Enum_Example3_src.rar (الحجم : 67.92 ك ب / التحميلات : 22)
}}}}
تم الشكر بواسطة:
#5
كما تلاحظون في الأكواد اعلاه انه في كل مرة نحاول أن نقوم بتحويل المتغيرات الموجودة داخل أي Enum وهي عبارة عن Strings إلي قيمتها العادية فإننا نبني دالة لكي نسترجع القيمة وربما لاحظتم في المثال الثالث أعلاه الدوال التالية


كود :
Private Function GetHatchStyleFromString(ByVal hatchString As String, ByVal ignoreCase As Boolean) As HatchStyle
Return CType([Enum].Parse(GetType(HatchStyle), hatchString, ignoreCase), HatchStyle)
End Function

Private Function GetContentAlinmentFromString(ByVal hatchString As String, ByVal ignoreCase As Boolean) As ContentAlignment
Return CType([Enum].Parse(GetType(ContentAlignment), hatchString, ignoreCase), ContentAlignment)
End Function

Private Function GetKnowColorString(ByVal ColorName As String, ByVal ignoreCase As Boolean) As KnownColor
Return CType([Enum].Parse(GetType(KnownColor), ColorName, ignoreCase), KnownColor)
End Function

Private Function GetDashStyleString(ByVal ColorName As String, ByVal ignoreCase As Boolean) As DashStyle
Return CType([Enum].Parse(GetType(DashStyle), ColorName, ignoreCase), DashStyle)
End Function
بالتأكيد ليس منطقيا ان نكتب دالة لكل Enum علي حدة بل الأفضل أن نكتب دالة واحدة فقط نستفيد بها في استرجاع قيمة الثوابت الموجودة داخل كل Enum وبهذا نقلل من حجم الكود المكتوب.

لذلك الدالة التالية يمكن أن تحل محل اي دالة من الدوال الأربعة أعلاه بل أيضا من الممكن استخدامها مع أي Enum وكما ستلاحطون فإنه قد تم استخدام Generics لبناء الدالة ..........


كود :
Private Function StringToEnum(Of T)(ByVal value As String, ByVal ignoreCase As Boolean) As T
If [Enum].IsDefined(GetType(T), value) Then
Return CType([Enum].Parse(GetType(T), value, ignoreCase), T)
End If
Throw New ArgumentException("value is not Enum")
End Function
والكود التالي يوضح التعديلات الجديدة بالمثال الثالث وستلاحظون ان الكود اصبح اقل من الكود الموجود بالمثال الثالث


كود :
Imports System.Drawing.Drawing2D

Public Class Form1

Private align As ContentAlignment = ContentAlignment.TopLeft
Private clr As Color = Color.Empty
Private hatch As HatchStyle = Nothing
Private pType As DashStyle = DashStyle.Dash

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
FillComboBoxsWithEnumData()
End Sub

Private Sub FillComboBoxsWithEnumData()
' Fill ComboBox1 with HatchStyle Enum
For Each hatchStyleObject As Object In [Enum].GetValues(GetType(HatchStyle))
If Not ComboBox1.Items.Contains(hatchStyleObject) Then ComboBox1.Items.Add(hatchStyleObject)
Next

' Fill ComboBox2 with ContentAlignment Enum
For Each contentAlignmentObject As Object In [Enum].GetValues(GetType(ContentAlignment))
If Not ComboBox2.Items.Contains(contentAlignmentObject) Then ComboBox2.Items.Add(contentAlignmentObject)
Next

' Fill ComboBox3 with KnowColor Enum
For Each knownColorObject As Object In [Enum].GetValues(GetType(KnownColor))
If Not ComboBox3.Items.Contains(knownColorObject) Then ComboBox3.Items.Add(knownColorObject)
Next

' Fill ComboBox4 with DashStyle Enum
For Each dashStyleObject As Object In [Enum].GetValues(GetType(DashStyle))
If Not ComboBox4.Items.Contains(dashStyleObject) Then ComboBox4.Items.Add(dashStyleObject)
Next
End Sub

Private Function StringToEnum(Of T)(ByVal value As String, ByVal ignoreCase As Boolean) As T
If [Enum].IsDefined(GetType(T), value) Then
Return CType([Enum].Parse(GetType(T), value, ignoreCase), T)
End If
Throw New ArgumentException("value is not Enum")
End Function

Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
hatch = StringToEnum(Of HatchStyle)(Me.ComboBox1.SelectedItem.ToString, True)
Invalidate()
End Sub

Private Sub ComboBox2_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox2.SelectedIndexChanged
align = StringToEnum(Of ContentAlignment)(Me.ComboBox2.SelectedItem.ToString, False)
Invalidate()
End Sub

Private Sub ComboBox3_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox3.SelectedIndexChanged
clr = Color.FromKnownColor(StringToEnum(Of KnownColor)(Me.ComboBox3.SelectedItem.ToString, True))
Invalidate()
End Sub

Private Sub ComboBox4_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox4.SelectedIndexChanged
pType = StringToEnum(Of DashStyle)(Me.ComboBox4.SelectedItem.ToString, True)
Invalidate()
End Sub

' Paint Something in the Form
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)

Dim TestRectangle As New Rectangle(10, 10, 200, 200)
Dim frameRect As Rectangle = TestRectangle
frameRect.X -= 4
frameRect.Y -= 4
frameRect.Width += 8
frameRect.Height += 8

Using obrush As New Drawing2D.LinearGradientBrush(frameRect, ControlPaint.Light(clr), ControlPaint.Dark(clr), Drawing2D.LinearGradientMode.Vertical)
e.Graphics.FillRectangle(obrush, frameRect)
Using framePen As New Pen(Brushes.Black)
framePen.DashStyle = pType
e.Graphics.DrawRectangle(framePen, frameRect)
End Using
End Using

Using hBrush As New Drawing2D.HatchBrush(hatch, clr)
e.Graphics.FillRectangle(hBrush, TestRectangle)
Using borderPen As New Pen(clr)
borderPen.DashStyle = pType
e.Graphics.DrawRectangle(borderPen, TestRectangle)
End Using
End Using

If Me.Text IsNot Nothing Then
Dim format As New StringFormat()
format.LineAlignment = StringAlignment.Center
format.Trimming = StringTrimming.EllipsisCharacter
Select Case align
Case ContentAlignment.BottomCenter
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Far
Exit Select
Case ContentAlignment.BottomLeft
format.Alignment = StringAlignment.Near
format.LineAlignment = StringAlignment.Far
Exit Select
Case ContentAlignment.BottomRight
format.Alignment = StringAlignment.Far
format.LineAlignment = StringAlignment.Far
Exit Select
Case ContentAlignment.MiddleCenter
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Center
Exit Select
Case ContentAlignment.MiddleLeft
format.Alignment = StringAlignment.Near
format.LineAlignment = StringAlignment.Center
Exit Select
Case ContentAlignment.MiddleRight
format.Alignment = StringAlignment.Far
format.LineAlignment = StringAlignment.Center
Exit Select
Case ContentAlignment.TopCenter
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Near
Exit Select
Case ContentAlignment.TopLeft
format.Alignment = StringAlignment.Near
format.LineAlignment = StringAlignment.Near
Exit Select
Case ContentAlignment.TopRight
format.Alignment = StringAlignment.Far
format.LineAlignment = StringAlignment.Near
Exit Select
End Select
Dim fnt As New Font("Times /new Roman", 25.0F, FontStyle.Bold)
Using sb As New SolidBrush(Color.White)
e.Graphics.DrawString(Me.Text, fnt, sb, TestRectangle, format)
End Using
End If

End Sub

End Class
الكود الموجود بالمرفقات بنسخة الفيجوال استوديو 2010

في المشاركات اللاحقة سوف نناقش كيف نستفيد أكثر من Enum و بطرق أخري مختلفة

تقبلوا تحياتي ولا تنسونا في دعائكم..............

أخوكم عمر


الملفات المرفقة
.rar   Enum_Example4_src.rar (الحجم : 67.58 ك ب / التحميلات : 23)
}}}}
تم الشكر بواسطة:
#6

اقتباس:
[TABLE="width: 100%"]
[TR]
[TD="class: alt2"]مراقبنا العزيز سيلفر أعجبني موضوعك لكن تمنيت
أن يكون الطرح أفضل لأنك لما تطرح فكرة صغيرة ويستوعبها الجميع ويبدأو بطرح
أفكار تطورها أفضل من شرح كتاب كامل ويالله من يفهم[/TD]
[/TR]
[/TABLE]

الأخ الفاضل vb_net

دعني أوضح لك الهدف من الموضوع

فكرة المقال مبنية علي تحويل أي Enum الي مجموعة من Items وهذه Items عبارة عن String ومن ثم نضيف كل String موجود داخل Enum إلي كومبوبوكس كونترول أو أي كونترول أخر يقبل النوع Items وبعد إضافة هذه Items نحتاج الي الحصول علي قيمتها الأصلية داخل Enum ولذلك نحتاج الي تحويلها من String To Enum مرة ثانية ثم أخر شئ نستفيد بها بشكل ما


ولتطبيق الفكرة راجع المثال الموجود بالمرفقات وهو بنسخة الفيجوال 2010 وإن لم تكن تمتلك نسخة 2010 يمكنك كتابة الكود الخاص بالمثال كالتالي:
ولتطبيق الكود : أضف إلي الفورم كومبوبوكس و Panel وداخل هذه Panel أضف باتون
والكود ببساطة يستخدم الخاصة Dock في تغيير وضعية الباتون داخل Panel وذلك عندما يتم إختيار اي عنصر موجود في الكومبوبوكس


كود :
Public Class Form1

Private styledock As DockStyle = DockStyle.None

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' Fill ComboBox1 with HatchStyle Enum
For Each dockStyleObject As Object In [Enum].GetValues(GetType(DockStyle))
If Not ComboBox1.Items.Contains(dockStyleObject) Then ComboBox1.Items.Add(dockStyleObject)
Next
End Sub

Private Function StringToEnum(Of T)(ByVal value As String, ByVal ignoreCase As Boolean) As T
If [Enum].IsDefined(GetType(T), value) Then
Return CType([Enum].Parse(GetType(T), value, ignoreCase), T)
End If
Throw New ArgumentException("value is not Enum")
End Function

Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
styledock = StringToEnum(Of DockStyle)(Me.ComboBox1.SelectedItem.ToString, True)
Me.Button1.Dock = styledock
End Sub

End Class
تقبل تحياتي
أخوك عمر


الملفات المرفقة
.rar   Enum_Example5_src.rar (الحجم : 60.84 ك ب / التحميلات : 22)
}}}}
تم الشكر بواسطة:
#7
كاتب المشاركة : Islam Ibrahim

شكرًا لك.

لكن ما دمت قد استخدمت Generics فأنا أفضل في هذه الحالة استخدام Generic TryParse Method الموجودة في الكلاس Enum ولكن تحتاج في هذه الحالة لإضافة Generic Constraint ليكون النوع T عبارة عن Value Type لأن ال Enum هي عبارة عن Value Types :


كود :
[color=#000000][COLOR=#0000bb]    [/color][color=#007700]public static class [/color][COLOR=#0000bb]EnumExtensions
    [/COLOR][COLOR=#007700]{  
        public static [/COLOR][color=#0000bb]T ToEnum[/color][color=#007700]<[/color][color=#0000bb]T[/color][color=#007700]>([/color][color=#0000bb]this string enumValue[/color][COLOR=#007700],  
            [/COLOR][color=#0000bb]bool ignoreCase[/color][COLOR=#007700])
            [/COLOR][color=#0000bb]where T [/color][color=#007700]: [/color][COLOR=#0000bb]struct    
        [/COLOR][COLOR=#007700]{
            [/COLOR][color=#0000bb]T value[/color][COLOR=#007700];
            if ([/COLOR][color=#0000bb]Enum[/color][color=#007700].[/color][color=#0000bb]TryParse[/color][color=#007700]<[/color][color=#0000bb]T[/color][color=#007700]>([/color][color=#0000bb]enumValue[/color][color=#007700], [/color][color=#0000bb]ignoreCase[/color][color=#007700], [/color][color=#0000bb]out value[/color][COLOR=#007700]))
                return [/COLOR][color=#0000bb]value[/color][COLOR=#007700];
            return default([/COLOR][color=#0000bb]T[/color][COLOR=#007700]);
        }

    }  
[/COLOR][color=#0000bb][/color][/COLOR]

ويمكن استخدامها في هذه الحالة مع أي String بالطريقة التالية , وفي حال لم تكن القيمة المدخلة صحيحة سيقوم بإرجاع القيمة الافتراضية (التي تحمل الفيمة 0 عادةً) .


كود :
[color=#000000][COLOR=#0000bb][/color][color=#007700]var [/color][color=#0000bb]enumValue [/color][color=#007700]= [/color][color=#dd0000]"None"[/color][color=#007700].[/color][color=#0000bb]ToEnum[/color][color=#007700]<[/color][color=#0000bb]DockStyle[/color][color=#007700]>([/color][color=#0000bb]true[/color][COLOR=#007700]);  
[/COLOR][color=#0000bb][/color][/COLOR]
}}}}
تم الشكر بواسطة:
#8
كاتب المشاركة : silverlight

الأخ الفاضل إسلام

شكرا علي مرورك وعلي الكود

لكني أعقد أنه لا يوجد فارق كبير بين اسخدام Enum.Prase و ُEnum.TryPrase فكلاهما يقوم بتحويل String الخاص بالعناصر الموجودة في Enum من قيمة أو إسم الي Object

عموما الفارق بين الدالتين ضئيل فأحدهما وهي Enum.Prase تطلق Exception في حالة إذا كانت القيم التي تم تمريرها ليست Enum أما الأخري فهي تسترجع Boolean يحدد نجاح الدالة في تحويل عناصر Enum لأنها تعتمد علي جملة Try......Catch وبالتالي فهي لا تطلق Exception في حالة تمرير قيم أخري غير Enum ويفضل استخدام TryPrase في حالة أننا لم نكن متأكدين أن القيمة التي تم تمريرها ليست Enum بشكل عام وفي كلتا الحالتين الدالة ستعود بنفس القيمة المطلوبة لأننا نمرر لها القيمة بالشكل الصحيح

علي سبيل المثال في الكود الموجود بالمشاركة رقم 7 لن يتم إطلاق Exception وتحديدا في السطر التالي من الكود

كود :
styledock = StringToEnum(Of DockStyle)(Me.ComboBox1.SelectedItem.ToString, True)
لكن لو كتبنا الكود بالشكل التالي فسيتم إطلاق EXception وهو Value is Not Enum


كود :
styledock = StringToEnum(Of DockStyle)(Me.ComboBox1.SelectedItem, True)
Enum.Parse

Enum.TryParse

بالنهاية وبصفة شخصة أنا أفضل استخدام Enum.Prase لأنها تطلق Exception وبالتالي فهي مفيدة في مرحلة Design

تقبل تحياتي
}}}}
تم الشكر بواسطة:
#9
كاتب المشاركة : Islam Ibrahim

في الواقع الغرض من استخدام Generic TryParse هو اختصار الكود قدر المستطاع , وحيث أني لم أنتبه إلى أن هذه الدالة مضافة حديثًا إلى .NET 4.0 ولم تكن موجود في الإصدارات السابقة وعمليًا فهي تقوم بنفس العمل الذي كتبته في الدالة StringToEnum و لكن الغرض الآخر منها هو إرجاع Fallback value في حال كانت المدخلات خاطئة , بدل إطلاق استثناء , خصوصاً عندما تتوقع أن تحدث أخطاء في إدخالات المستخدم .

بالنسبة لمسالة التطوير أو ال Design فأعتقد أن هناك طرق أفضل من إطلاق الاستثناءات كاستخدام Processor Directives أو Conditional Attribute .
}}}}
تم الشكر بواسطة:
#10
كاتب المشاركة : silverlight

اقتباس:
[TABLE="width: 100%"]
[TR]
[TD="class: alt2"]بالنسبة لمسالة التطوير أو ال Design فأعتقد أن هناك طرق أفضل من إطلاق الاستثناءات كاستخدام Processor Directives أو Conditional Attribute [/TD]
[/TR]
[/TABLE]

أعتقد أنك تقصد Preprocessor Directives ......؟؟؟؟؟؟ متهيالي أنها تستخدم للتناسق بين لغات البرمجة وتخطي أجزاء معينة من السورس كود في حالة وجود أخطاء....

Preprocessor Directives

عموما ياإسلام القارئ لايحتاج الي أن يدخل في متاهة........ ومثل هذه الموضوعات من الممكن أن يتم مناقشتها علي حدة عن طريق كتابة مقالات مفصلة عنها
}}}}
تم الشكر بواسطة:


المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  [مقال] تشغيل برمجيات الدوت نت بدون تنصيب النت فروم ويرك m0075 13 4,135 13-02-14, 08:29 PM
آخر رد: Omar Mekkawy
  تفقيط الارقام فى الدوت نت مبرمج أوتار 16 3,738 30-08-13, 01:01 AM
آخر رد: abatenovtch
  التــعامل مع cmd من خلال الدوت نت مبتدئ في الاحتراف 2 532 24-04-13, 07:58 PM
آخر رد: مبتدئ في الاحتراف
  مقال- كيفية الاستغناء عن الداتا بيز التقليدية في برامجنا – ألجزء الأول RaggiTech 1 1,247 06-10-12, 12:23 AM
آخر رد: RaggiTech
  مقال- تطوير الكونترول Property Attributes الجزء الثالث RaggiTech 0 365 06-10-12, 12:20 AM
آخر رد: RaggiTech
  مقال- تطوير الكونترول Skin Control RaggiTech 0 531 06-10-12, 12:08 AM
آخر رد: RaggiTech
  مقال- كيف تصنع ملفات المساعدة Help Files وتربطها مع برنامجك RaggiTech 0 728 05-10-12, 07:30 PM
آخر رد: RaggiTech
  مقال- تطوير الفورم رسم الفورم باستخدام +GDI وتحريكه Moving و تغيير أبعاده Resize RaggiTech 2 878 05-10-12, 07:00 PM
آخر رد: RaggiTech
  مقال- الكومبو بوكس ComboBox كيف تضيف أيقونات RaggiTech 0 770 05-10-12, 06:54 PM
آخر رد: RaggiTech
  مقال- أفكار في الدوت نت كبف تصنع ColorPicker RaggiTech 0 438 05-10-12, 06:53 PM
آخر رد: RaggiTech

التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم