تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
تطوير الكونترول Rendering Control الجزء الخامس
#1
كاتب الموضوع : silverlight

الموضوع : تطوير الكزنترول Rendering Control
اللغة المستخدمة: الفيجوال بيسك
التطبيق: فيجوال استوديو 2005 و 2008
المستوي: التقييم متروك للقارئ
إعداد: مهندس / عمر أمين إبراهيم

ماذا تعني كلمة Rendering ؟

الإجابة ببساطه شديدة أن هذه الكلمة تعني رسم واجهة التطبيق التي يتعامل معها المستخدم أو كما يطلق عليها User Interface ولكي نقوم بذلك فإننا نستخدم VisualStyles الموجودة في نظام التشغيل مثل Windows XP علي سبيل المثال وعموما واجهة التطبيق ممكن تكون أي شئ إما كونترول معين أو فورم.

ولتوضيح الأمر قليلا لو نظرت الي أي فورم عادي ستجد في اعلاه مجموعه من الباتون مثل Close و Maximize و Minimize وهي مناطق لا تستطيع تغييرها فهي موجودة في كل فورم تقوم بإنشائه في الفيجوال استوديو وكل هذه الباتون تم رسمها باستخدام VisualStyles Class

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

منذ سنوات وتحديدا عندما قامت مايكروسوفت بإصدار Windows XP كلنا لاحظنا التكنولوجيا المستخدمة في إظهار الكونترول أو الفورم بشكل لطيف يشد انتباه المستخدم كل هذا تم باستخدام VisualStyles

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

لن أطيل عليكم كثيرا في الحديث عن تاريخ VisualStyles وكيف تم صنعها فأنتم تعلمون عنها الكثير ولكن كيف لنا أن نغير شكل الكونترول أو تحديدا كيف نغير في شكل الكونترول التقليدي الموجود مع الفيجوال استوديو باستخدام Rendering

في الواقع هناك القليل من Classes التي تتعامل مع Control Rendering وهي مقسمة الي فئتان بعضها يسمح برسم الكونترول سواء استخدمنا VisualStyles أم لا والبعض الأخر منها يحتاج الي وجود VisualStyles وبدونها سيحدث خطأ أو Error أثناء رسم هذه الكونترول وهذه الكونترول مرتبه كالأتي
Button
CheckBox
GroupBox
RadioButton

تلك العناصر الأربعة كل منها يملك كلاس خاص به يقوم بعمل Rendering وكما أسلفنا فإن هذه Classes تنتمي الي الفئة الأولي التي من الممكن استخدامها لرسم الكونترول في وجود أو عدم وجود VisualStyles

أما الفئة الثانية والتي تحتاج الي وجود VisualStyles فهي مقسمة كما يلي وأيضا كل منها يمتلك كلاس خاص به يقوم بعملية Rendering وهذه الكلاس كالأتي
ComboBox
ProgressBar
ScrollBar
Tab
Textbox
TrackBar

لو بحثت جيدا في مواقع مايكروسوفت ستجد أنها قد قامت بإعطاء فكرة عن كيفية التعامل مع هذه الكونترول تحديدا وكيفية استخدام Rendering Classes في تغيير شكل الكونترول أو تصميمه من الصفر أو مثلما يقولون From Scratch
لكن مايكروسوفت استخدمت VisualStyles الموجودة في نظام التشغيل لكي ترسم هذه الكونترول المختلفة إذن الأمر في النهاية لا يوجد هناك شيئا جديدا لكي نستفيد منه في تصميم كونترول له شكل مبهر للمستخدم. كيف نجد حلا لهه المعضلة؟ الامر بسيط جدا يجب أن نبني VisualStyles Classes بأنفسنا لكي نستطيع تغيير الشكل الكلاسيكي للكونترول المختلفة

كيف نبني Our VisualStyles Classes لكي نحصل علي كونترول له شكل مناسب ومختلف عن الكونترول الكلاسيكي الموجود في الفيجوال استوديو إن هدف هذا المقال هو الإجابة علي هذا السؤال تحديدا ولكي نفعل ذلك سوف نعطي مثالا عمليا مثل ScrollBar

لن ادخل في تفاصيل بناء ScrollBar فهناك أمثلة كثيرة علي ذلك موجودة في الكثير من المواقع وسوف اختار مثالا موجودا بالفعل في مواقع مايكروسوفت والكود التالي يوضح المثال الذي أعطته مايكروسوفت لبناء ScrollBar عن طريق الوراثة Inherits للكونترول كلاس

لنفتح Windows Application Form ونضيف له الكلاس التالي ولسوف نطلق عليه MSCustomScrollBar


كود :
Imports System.Windows.Forms.VisualStyles

Public Class MsCustomScrollBar

Inherits Control

Private clickedBarRectangle As Rectangle
Private thumbRectangle As Rectangle
Private leftArrowRectangle As Rectangle
Private rightArrowRectangle As Rectangle
Private leftArrowClicked As Boolean = False
Private rightArrowClicked As Boolean = False
Private leftBarClicked As Boolean = False
Private rightBarClicked As Boolean = False
Private thumbClicked As Boolean = False
Private thumbState As ScrollBarState = ScrollBarState.Normal
Private leftButtonState As ScrollBarArrowButtonState = _
ScrollBarArrowButtonState.LeftNormal
Private rightButtonState As ScrollBarArrowButtonState = _
ScrollBarArrowButtonState.RightNormal

' This control does not allow these widths to be altered.
Private thumbWidth As Integer = 15
Private arrowWidth As Integer = 17

' Set the right limit of the thumb's right border.
Private thumbRightLimitRight As Integer = 0

' Set the right limit of the thumb's left border.
Private thumbRightLimitLeft As Integer = 0

' Set the left limit of thumb's left border.
Private thumbLeftLimit As Integer = 0

' Set the distance from the left edge of the thumb to the
' cursor tip.
Private thumbPosition As Integer = 0

' Set the distance from the left edge of the scroll bar track to
' the cursor tip.
Private trackPosition As Integer = 0

' This timer draws the moving thumb while the scroll arrows or
' track are pressed.
Private WithEvents progressTimer As New Timer()

Public Sub New()
With Me
.Location = New Point(10, 10)
.Width = 200
.Height = 20
.DoubleBuffered = True
End With
SetUpScrollBar()
progressTimer.Interval = 20
End Sub

' Calculate the sizes of the scroll bar elements.
Private Sub SetUpScrollBar()

clickedBarRectangle = Me.ClientRectangle
thumbRectangle = New Rectangle(ClientRectangle.X + _
Me.ClientRectangle.Width / 2, Me.ClientRectangle.Y, _
thumbWidth, Me.ClientRectangle.Height)
leftArrowRectangle = New Rectangle(Me.ClientRectangle.X, _
Me.ClientRectangle.Y, arrowWidth, Me.ClientRectangle.Height)
rightArrowRectangle = New Rectangle(Me.ClientRectangle.Right - _
arrowWidth, Me.ClientRectangle.Y, arrowWidth, _
Me.ClientRectangle.Height)

' Set the default starting thumb position.
thumbPosition = thumbWidth / 2

' Set the right limit of the thumb's right border.
thumbRightLimitRight = Me.ClientRectangle.Right - arrowWidth

' Set the right limit of the thumb's left border.
thumbRightLimitLeft = thumbRightLimitRight - thumbWidth

' Set the left limit of the thumb's left border.
thumbLeftLimit = Me.ClientRectangle.X + arrowWidth
End Sub

' Draw the scroll bar in its normal state.
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
MyBase.OnPaint(e)

' Visual styles are not enabled.
If Not ScrollBarRenderer.IsSupported Then
Me.Parent.Text = "CustomScrollBar Disabled"
Return
End If

Me.Parent.Text = "CustomScrollBar Enabled"

' Draw the scroll bar track.
ScrollBarRenderer.DrawRightHorizontalTrack(e.Graphics, _
Me.ClientRectangle, ScrollBarState.Normal)

' Draw the thumb and thumb grip in the current state.
ScrollBarRenderer.DrawHorizontalThumb(e.Graphics, _
thumbRectangle, thumbState)
ScrollBarRenderer.DrawHorizontalThumbGrip(e.Graphics, _
thumbRectangle, thumbState)

' Draw the scroll arrows in the current state.
ScrollBarRenderer.DrawArrowButton(e.Graphics, _
leftArrowRectangle, leftButtonState)
ScrollBarRenderer.DrawArrowButton(e.Graphics, _
rightArrowRectangle, rightButtonState)

' Draw a highlighted rectangle in the left side of the scroll
' bar track if the user has clicked between the left arrow
' and thumb.
If leftBarClicked Then
clickedBarRectangle.X = thumbLeftLimit
clickedBarRectangle.Width = thumbRectangle.X - thumbLeftLimit
ScrollBarRenderer.DrawLeftHorizontalTrack(e.Graphics, _
clickedBarRectangle, ScrollBarState.Pressed)

' Draw a highlighted rectangle in the right side of the scroll
' bar track if the user has clicked between the right arrow
' and thumb.
ElseIf rightBarClicked Then
clickedBarRectangle.X = thumbRectangle.X + _
thumbRectangle.Width
clickedBarRectangle.Width = thumbRightLimitRight - _
clickedBarRectangle.X
ScrollBarRenderer.DrawRightHorizontalTrack(e.Graphics, _
clickedBarRectangle, ScrollBarState.Pressed)
End If
End Sub

' Handle a mouse click in the scroll bar.
Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
MyBase.OnMouseDown(e)

If Not ScrollBarRenderer.IsSupported Then
Return
End If

' When the thumb is clicked, update the distance from the left
' edge of the thumb to the cursor tip.
If thumbRectangle.Contains(e.Location) Then
thumbClicked = True
thumbPosition = e.Location.X - thumbRectangle.X
thumbState = ScrollBarState.Pressed

' When the left arrow is clicked, start the timer to scroll
' while the arrow is held down.
ElseIf leftArrowRectangle.Contains(e.Location) Then
leftArrowClicked = True
leftButtonState = ScrollBarArrowButtonState.LeftPressed
progressTimer.Start()

' When the right arrow is clicked, start the timer to scroll
' while arrow is held down.
ElseIf rightArrowRectangle.Contains(e.Location) Then
rightArrowClicked = True
rightButtonState = ScrollBarArrowButtonState.RightPressed
progressTimer.Start()

' When the scroll bar is clicked, start the timer to move the
' thumb while the mouse is held down.
Else
trackPosition = e.Location.X
If e.Location.X < Me.thumbRectangle.X Then
leftBarClicked = True
Else
rightBarClicked = True
End If
progressTimer.Start()
End If

Invalidate()
End Sub

' Draw the track.
Protected Overrides Sub OnMouseUp(ByVal e As MouseEventArgs)
MyBase.OnMouseUp(e)

If Not ScrollBarRenderer.IsSupported Then
Return
End If

' Update the thumb position, if the new location is within
' the bounds.
If thumbClicked Then
thumbClicked = False
thumbState = ScrollBarState.Normal
If e.Location.X > thumbLeftLimit + thumbPosition And _
e.Location.X < thumbRightLimitLeft + thumbPosition Then
thumbRectangle.X = e.Location.X - thumbPosition
thumbClicked = False
End If

' If one of the four thumb movement areas was clicked,
' stop the timer.
ElseIf leftArrowClicked Then
leftArrowClicked = False
leftButtonState = ScrollBarArrowButtonState.LeftNormal
progressTimer.Stop()

ElseIf rightArrowClicked Then
rightArrowClicked = False
rightButtonState = ScrollBarArrowButtonState.RightNormal
progressTimer.Stop()

ElseIf leftBarClicked Then
leftBarClicked = False
progressTimer.Stop()

ElseIf rightBarClicked Then
rightBarClicked = False
progressTimer.Stop()
End If

Invalidate()
End Sub

' Track mouse movements if the user clicks on the scroll bar thumb.
Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)
MyBase.OnMouseMove(e)

If Not ScrollBarRenderer.IsSupported Then
Return
End If

' Update the thumb position, if the new location is
' within the bounds.
If thumbClicked Then

' The thumb is all the way to the left.
If e.Location.X <= thumbLeftLimit + thumbPosition Then
thumbRectangle.X = thumbLeftLimit

' The thumb is all the way to the right.
ElseIf e.Location.X >= thumbRightLimitLeft + thumbPosition Then
thumbRectangle.X = thumbRightLimitLeft

' The thumb is between the ends of the track.
Else
thumbRectangle.X = e.Location.X - thumbPosition
End If

Invalidate()

End If
End Sub

' Recalculate the sizes of the scroll bar elements.
Protected Overrides Sub OnSizeChanged(ByVal e As EventArgs)
MyBase.OnSizeChanged(e)
SetUpScrollBar()
End Sub

' Handle the timer tick by updating the thumb position.
Private Sub progressTimer_Tick(ByVal sender As Object, _
ByVal myEventArgs As EventArgs) Handles progressTimer.Tick

If Not ScrollBarRenderer.IsSupported Then
Return
End If

' If an arrow is clicked, move the thumb in small increments.
If rightArrowClicked And thumbRectangle.X < thumbRightLimitLeft Then
thumbRectangle.X += 1

ElseIf leftArrowClicked And thumbRectangle.X > thumbLeftLimit Then
thumbRectangle.X -= 1

' If the track bar to right of the thumb is clicked, move the
' thumb to the right in larger increments until the right edge
' of the thumb hits the cursor.
ElseIf rightBarClicked And thumbRectangle.X < thumbRightLimitLeft _
And thumbRectangle.X + thumbRectangle.Width < trackPosition Then
thumbRectangle.X += 3

' If the track bar to left of the thumb is clicked, move the
' thumb to the left in larger increments until the left edge
' of the thumb hits the cursor.
ElseIf leftBarClicked And thumbRectangle.X > thumbLeftLimit And _
thumbRectangle.X > trackPosition Then
thumbRectangle.X -= 3
End If

Invalidate()
End Sub

End Class
}}}}
تم الشكر بواسطة:
#2

الأن نقوم بعمل Build وسنجد الكونترول موجود في Toolbox وبعد ذلك نضيفه الي الفورم مثله مثل أي كونترول أخر

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

فقط عزيزي القارئ أريد منك أن تلاحظ كلمة واحدة وهي ScrollBarRenderer هذه الكلمة أو الجزئية من الكود هي ما تعنينا تماما

وهي التي من أجلها سوف نضيف كلاس أخر الي الفورم ولنطلق عليه MyScrollBarRenderer وفي هذه الكلاس سنقوم بالجزء الأكبر من العمل المطلوب لتغيير الشكل الكلاسيكي للكونترول أيضا سوف أضيف الي الفورم Module وليكن اسمه MyModule وهنا سوف نضيف بعض المتغيرات وهي جميعها عبارة عن Colors لكي نستخدمها بشكل عام في المشروع.

لكن قبل أن نبدأ في كتابة الكود الخاص بالكلاس MyScrollBarRenderer لنلقي نظرة سريعة علي الكلاس الأصلي الذي هو من إنتاج مايكروسوفت ولنتذكر جيدا أن أي كلاس ممكن بناؤه من جديد بشرط أن ندرس عناصره المختلفة جيدا وأن نكون علي دراية بكيفية كتابة الكود الخاص به ثانية بطريقتنا الخاصة.

لو نظرنا الي الكلاس الخاص بشركة مايكروسوفت وهو ScrollBarRenderer سنجد أن عناصره كالأتي
هذا الكلاس يمتلك Property واحدة وهي IsSupported بالإضافة الي مجموعة من الطرقMethods المختلفة ومعظمها يختص برسم الكونترول
إذن كل ما علينا فعله هو إعادة بناء الكود الخاص بهذه الطرق والصفات الموجودة في الكونترول الخاص بشركة مايكروسوفت

الطرق المطلوب إعادة كتابة الكود لها عبارة عن الأتي
DrawArrowButton
DrawHorizontalThumb
DrawHorizontalThumbGrip
DrawLeftHorizontalTrack
DrawLowerVerticalTrack
DrawRightHorizontalTrack
DrawSizeBox
DrawUpperVerticalTrack
DrawVerticalThumb
DrawVerticalThumbGrip
GetSizeBoxSize
GetThumbGripSize

لنأخذ مثالا سريعا علي أحد هذه الطرق وبالتالي سوف تكون باق الطرق تكرارية بالنسبة لنا
والكود لهذه الطريقة كما أوضحت مايكروسوفت يكتب كالأتي



كود :
Public Shared Sub DrawArrowButton(ByVal g As Graphics, ByVal bounds As Rectangle, ByVal state As ScrollBarArrowButtonState)

End Sub
لا تتعجل عزيزي القارئ فهذه مجرد البداية فنحن نحتاج الي أن نكتب الكود الخاص بهذا ٍSub
لكن قبل أن نفعل ذّلك للنظر الي طبيعة تكوين هذا Sub وتحديدا لما يوجد بين الأقواس سنجد أن هناك ثلاثة متغيرات وهم علي التوالي

g وهي عبارة عن GDI Graphics

bounds وهي عبارة عن System.Drawing.Rectangle

ScrollBarArrowButtonState وهو عبارة عن Enum وتحديدا هذا المتغير هو ما يجب أن نهتم به لأن من خلاله سوف نحدد طريقة رسم السهم في حالاته المختلفة وهي Disabled State و Hot State و Normal State و Pressed State إذن كل ما علينا عمله هو استخدام Select Case ومن ثم نقوم برسم السهم عن طريق GDI Graphics داخل حدود bounds

وطبعا سوف نكرر نفس الأسلوب لباقي الطرق الاخري الموجودة داخل ScrollBarRenderer Class وكل المطلوب الأن هو التلاعب بالألوان ومن ثم نرسم bounds أو ممكن نجهز بعض الصور بأي برنامج رسم ونضيفها للمشروع ومن ثم نرسمها داخل bounds
دي الفكرة ببساطة أتمني إنها تكون واضحة عموما أنا كتبت الكلاس كله وكتبت الكود لبعض الطرق للتوضيح فقط لا غير وإن أردت عزيزي القارئ أن تكتب باق الكود فالأمر أصبح واضحا وكل ما عليك أن تفعله هو أن تكتب باق الاكواد بنفس الطريقة التي قمت أنا بإتباعها في كتابة جزء من الطرق Methods وبعد أن تنتهي سيكون لديك كلاس كامل بديل للكلاس الذي صممته مايكروسوفت

المثال الموجود بالمرفقات يوضح الكلاس الجديد الذي سوف يستخدم كبديل لما صممته مايكروسوفت وهو ليس كاملا لأنك ستكتشف عزيزي القارئ أن الموضوع محتاج وقت طويل وتنظيم ودقة لكي تستطيع بناء الكلاس كاملا ولو لديك الوقت لذلك فمرحبا بك في زمرة مطوري البرامج
تبقي القليل عزيزي القارئ وننتهي من الأمر و الأن بعد أن قمنا بإعادة بناء الكلاس الذي صممته مايكروسوفت وهو ScrollBarRenderer وأطلقنا عليه اسم جديد وهو MyScrollBarRenderer لم يتبقي إلا أن نقوم باستبدال كل كلمة بمعني ScrollBarRenderer الموجودة داخل الكلاس MyCustomScrollBar بالاسم الجديد الي صممناه وهو MyScrollBarRenderer ثم قم بعمل Build ولسوف تجد الكلاسان MSCustomScrollBar وأيضا MyCustomScrollBar موجودان في Toolbox قم بإضافتهما الي الفورم ولسوف تري الفارق شاسعا بينهما

أتمني يكون الأمر واضح وطبعا بنفس الأسلوب يمكن بناء أي كونترول أخر يمتلك Renderer Class خاص به أما إذا أرت أن تبني VisualStyles كلها فمرحبا بك عزيزي القارئ فالأمر سوف يحتاج الي الكثير والكثير من الجهد والوقت ولا تنسي أن مايكروسوفت لديها فريق عمل كبير جدا أما أنت فليس لديك إلا قدراتك الشخصية إذن توكل علي الله وحاول تصنع شيئا لوحدك أو تعاون مع أصدقائك وزملاؤك لبناء هذه النوعية من الكلاس........................

هناك ملحوظة هامة جدا سنقوم بالتعليق عليها وإظهارها للقارئ نظرا لأهميتها في تطوير الكونترول أو الفورم بشكل عام
لنفرض جدلا أن مستخدم الكمبيوتر وهنا أنا أتحدث عن الشخص العادي أو ما يطلق عليه End User وليس المبرمج تحديدا لنفرض أن هذا المستخدم في وقت ما قرر تغيير الفونت المستخدم في جهاز الكمبيوتر الخاص به عن طريق التغيير في Settings الخاصة بنظام التشغيل

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

في هذه الحالة فإن الكونترول الذي صممته سيكون مشوها وبالتالي سيكره المستخدم البرنامج وربما يبحث عن البديل الأفضل لما يريده فهو يتوقع شيئا مثاليا منك كمبرمج فأنت الشخص السوبر الذي عليه أن يفعل المستحيل لإرضاء المستخدم فأنت بالنسبة للمستخدم مثل الساحر هوديني الذي يتعامل مع الخيال والحلم
عموما الحل في كلمة واحدة انك سوف تتعامل مع SystemEvents.UserPreferenceChanged وهذا يعني أنك ستكتب هذا Sub أي أنك سوف تضيف Handler لهذا Sub وهو يضاف الي Control Constructor أي تحت Public Sub New ومن ثم تقوم بعمل Remove لهذا Handler في Control Dispose ويجب إزالة هذا Handler حتى لا يحدث Memory Leak وطبعا سنكتب الكود المناسب تحت هذا Sub لكي نتلافى أخطاء المستخدم طبعا لازم نعمل Imports الي Microsoft.Win32 والكود المفروض إضافته لحل هذه المشكلة سيكون كالأتي


كود :
Imports Microsoft.Win32
‘-------------------------
Public Sub New()
AddHandler SystemEvents.UserPreferenceChanged, AddressOf SystemEvents_UserPreferenceChanged
End Sub

Private Sub SystemEvents_UserPreferenceChanged(ByVal sender As Object, ByVal e As UserPreferenceChangedEventArgs)
If e.Category = UserPreferenceCategory.Window Then
Me.Font = SystemFonts.IconTitleFont
End If
End Sub

Private Sub MsCustomScrollBar_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed

RemoveHandler SystemEvents.UserPreferenceChanged, AddressOf SystemEvents_UserPreferenceChanged

End Sub
سنلاحظ أن الفونت قد تم ربطه الي شئ واحد فقط وهو SystemFonts.IconTitleFont

الخلاصة

عندما سوف تبني أي كلاس كاملا سوف تتغير نظرتك تماما لكتابة الكود فعندها فقط سوف تشعر كيف تحدث الأشياء وكما قلت سابقا أن أي كلاس صممته مايكروسوفت ممكن كتابته من جديد بشرط أن تعلم كيف تكتبه بنفسك وللمرة الثانية عزيزي القارئ أرجو منك أن تدرس أي كلاس جيدا وتدرس خصائصه ومكوناته ومن أين جاء فهذا سوف يساعدك كثيرا علي التقدم سريعا في عالم السحر والخيال وحينها فقط سيكون كتابة الكود متعة لن تستطيع التخلص منها ولسوف تري الأشياء بصورة مختلفة جدا

مرفق الكود بنسخة 2008

http://vb4arb.com/vb/uploaded/18_01349241432.zip

أتمني لكم النجاح والتوفيق

اخوكم عمر
}}}}
تم الشكر بواسطة:


المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  Control Finder Class silverlight 3 67 03-12-16, 06:11 AM
آخر رد: أبو عمر
  Generic Delegates & ًWindows Forms Control - Part 2 silverlight 0 197 19-01-16, 02:01 PM
آخر رد: silverlight
  Generic Delegates & ًWindows Forms Control - Part 1 silverlight 1 254 16-01-16, 06:35 PM
آخر رد: 10468
  [كود] Line Control silverlight 0 194 14-01-16, 03:03 PM
آخر رد: silverlight
  Retrieve Owner and Form of a Control silverlight 0 183 12-12-15, 05:28 AM
آخر رد: silverlight
  Capture Mouse Position within Control Coordinates silverlight 0 224 11-12-15, 10:30 PM
آخر رد: silverlight
  إيجاد جميع الكونترول الموجودة في الفورم Recursively Find All Controls in Form silverlight 0 507 26-05-15, 12:31 AM
آخر رد: silverlight
  تحويل الفيديو في برامجك-الجزء الثاني( إصلاح للمشاكل + تعديل للروابط + توضيح للأمر ) RaggiTech 1 716 10-12-14, 06:37 PM
آخر رد: abulayth
  الجزء الثالث من:كيف تجعل الـ Text Box ذكي!يترجم العمليات الحسابية ويخرج الناتج (الأقواس المتعددة) !! أنس محمود 9 2,083 06-12-14, 10:11 PM
آخر رد: RFEE3 ALSHAN
Rainbow Toolbox in VB.NET - Common Controls - Lesson One - Button Control Properties Genius Live 18 4,238 26-03-14, 09:21 PM
آخر رد: رابح11

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


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