الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

طريقة عمل Custom Property Editor

بدأه GHOST2010 في 19 يوليو 2009 · 6 رد · 3,999 مشاهدة · في قسم الدروس والمواضيع المتميزة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

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

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

فمثلا إذا نظرنا إلى خاصية من نوع Color ولتكن الخاصية BackColor فعند تغيير قيمتها يظهر محرر الخاصية بهذا الشكل

post-47088-1248005808_thumb.jpg

ولو نظرنا إلى خاصية من نوع Font ولتكن الخاصية Font لوجدنا محرر الخاصية مختلف قليلا وهو عبارة عن شاشة منفصلة بهذا الشكل

post-47088-1248005909_thumb.jpg

هذا هو ما يسمى بالـTypeEditor

هذه الفئة هى التى تخبر نافذة الخصائص كيف يتم تغيير وإظهار قيمة الخصائص المختلفة

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

بسم الله نبدأ ,,

الخطوة الأولى بالتأكيد هى فتح مشروع جديد من نوع WindowsApplication

ثم

نضيف فئة جديدة وليكن اسمها MyCustomControl وهى ستكون فأر التجارب :D

الكود الخاص بها بهذا الشكل

Public Class MyCustomControl
	Inherits UserControl

	Private _value As Integer

	Public Property Value() As Integer
		Get
			Return _value
		End Get
		Set(ByVal value As Integer)
			_value = value
		End Set
	End Property
End Class

كما هو واضح فى الكود ,, الفئة يتم وراثتها من الفئة UserControl وقمنا بإضافة خاصية واحدة فقط هى Value من النوع Integer

الآن لو قمنا بعمل ترجمة للمشروع سنجد أن الأداة الجديدة ظهرت فى شريط الأدوات

قم بإضافتها على الفورم وانظر إلى الخاصية Value وحاول التغيير فيها

ماذا لاحظت؟؟

بالتأكيد لم يتغير شئ :D :D

سنقوم الآن بكتابة محرر جديد للخاصية Value

نريد مثلا أن يتم تغيير قيمة الخاصية باستخدام TrackBar

قم بإضافة فئة جديدة بإسم MyValueEditor

الكود المبدئى لهذه الفئة سيكون بهذا الشكل

Imports System.Drawing.Design
Imports System.Windows.Forms.Design

Public Class MyValueEditor
	Inherits UITypeEditor

	Dim edsvc As IWindowsFormsEditorService
	Dim tb As TrackBar

End Class

قمنا أولا باستيراد مجال الأسماء Imports System.Drawing.Design وهو الذى يحتوى على الفئة التى قمنا بوراثتها وهى UITypeEditor ومجال الأسماء System.Windows.Forms.Design وهو يحتوى على الفئة IWindowsFormsEditorService وهى المسئولة عن إظهار محرر الخصائص الخاص بنا

وقمنا بتعريف متغير من نوع TrackBar والذى يمثل الأداة التى سنستخدمها كمحرر للخاصية

الآن بما أننا قمنا بالاشتقاق من الفئة UITypeEditor فأول خطوة سنقوم بها هى تغيير طريقة تحرير الخاصية عن طريق الوظيفة GetEditStyle والتى تعود بقيمة من النوع System.Drawing.Design.UITypeEditorEditStyle وهو يدعم ثلاثة أنواع للمحررات

None: استخدام الطريقة الافتراضية

DropDown: يتم إظهار سهم صغير بجوار الخاصية مثل أداة ComboBox كما هو موجود فى الخاصية BackColor

Modal: يتم تحرير الخاصية عن طريق نافذة أخرى مثل الخاصية Font

فى مثالنا هذا سنستخدم النوع الثانى DropDown

	Public Overrides Function GetEditStyle(ByVal context As System.ComponentModel.ITypeDescriptorContext) As System.Drawing.Design.UITypeEditorEditStyle
		Return UITypeEditorEditStyle.DropDown
	End Function

الآن سنقوم بالعمل على الوظيفة EditValue والتى يتم استدعاؤها عند قيام مستخدم الأداة بمحاولة تحرير الخاصية

ستكون بهذا الشكل

Public Overrides Function EditValue(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal provider As System.IServiceProvider, ByVal value As Object) As Object
		If provider IsNot Nothing Then
			edsvc = CType(provider.GetService(GetType(IWindowsFormsEditorService)), IWindowsFormsEditorService)
			If edsvc IsNot Nothing Then

				If tb Is Nothing Then
					tb = New TrackBar
					With tb
						.Maximum = 100
						.Minimum = 0
						AddHandler tb.MouseUp, AddressOf OnSelectValue
					End With
				End If

				If value IsNot Nothing AndAlso TypeOf value Is Integer Then
					tb.Value = value
				End If

				edsvc.DropDownControl(tb)
				value = tb.Value
			End If
		End If
		Return value
	End Function

Private Sub OnSelectValue(ByVal sender As Object, ByVal e As MouseEventArgs)
		edsvc.CloseDropDown()
	End Sub

نقوم بتهيئة قيمة edsvc عن طريق استدعاء الوظيفة GetService التابعة للكائن provider

الكائن edsvc هو المسئول عن إظهار المحرر الخاص بنا

بعد ذلك يتم التأكد من الكائن tb إذا كان nothing نقوم بتهيئته ونضع قيم لبعض خصائصه وأخبرنا المترجم أن يقوم باستدعاء الإجراء OnSelectValue عند تنفيذ الحدث MouseUp

فى جملة الشرط التالية يتم التأكد من المعامل value وهى تحمل قيمة الخاصية الحالية ونقوم باسنادها للخاصية Value التابعة للكائن tb

بعد أن قمنا بتهيئة المحرر الخاص بنا بقى علينا أن نقوم بإظهاره وذلك عن طريق استدعاء الإجراء DropDownControl التابع للكائن edsvc

عند تنفيذ الحدث MouseUp سيتم نقل التحكم إلى الإجراء OnSelectValue وكما هو واضح من الكود أن هذا الإجراء يقوم فقط بإخفاء المحرر عن طريق إستدعاء الإجراء CloseDropDown التابع للكائن edsvc

سيتم إعادة التحكم للوظيفة EditValue مرة أخرى بعد تنفيذ هذا الحدث عند السطر

value = tb.Value

قمنا بوضع القيمة التى اختارها المستخدم عن طريقة الـTrackBar فى المعامل value الذى يتم إرساله مرة أخرى إلى نافذة الخصائص

انتهينا من أول وأبسط محرر خصائص خاص بنا

إذهب الآن إلى الفورم وحاول تغيير قيمة الخاصية Value ,, ستجد المحرر أصبح بهذا الشكل

post-47088-1248065076_thumb.jpg

ملحوظة بسيطة

الكود السابق كله لن يعمل :D :D

لا تنزعج

فقط سنعدل جزء بسيط جدا فى كود الفئة MyCustomControl

يجب أن نخبر المترجم أن محرر الخاصية Value هو MyValueEditor

سيكون الكود النهائى للأداة بهذا الشكل

Imports System.ComponentModel
Imports System.Drawing.Design

Public Class MyCustomControl
	Inherits UserControl

	Private _value As Integer

	<Editor(GetType(MyValueEditor), GetType(UITypeEditor))> _
	Public Property Value() As Integer
		Get
			Return _value
		End Get
		Set(ByVal value As Integer)
			_value = value
		End Set
	End Property
End Class

وهذا هو الكود النهائى للمحرر

Imports System.Drawing.Design
Imports System.Windows.Forms.Design

Public Class MyValueEditor
	Inherits UITypeEditor

	Public Overrides Function GetEditStyle(ByVal context As System.ComponentModel.ITypeDescriptorContext) As System.Drawing.Design.UITypeEditorEditStyle
		Return UITypeEditorEditStyle.DropDown
	End Function

	Private edsvc As IWindowsFormsEditorService
	Dim tb As TrackBar

	Public Overrides Function EditValue(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal provider As System.IServiceProvider, ByVal value As Object) As Object
		If provider IsNot Nothing Then
			edsvc = CType(provider.GetService(GetType(IWindowsFormsEditorService)), IWindowsFormsEditorService)
			If edsvc IsNot Nothing Then

				If tb Is Nothing Then
					tb = New TrackBar
					With tb
						.Maximum = 100
						.Minimum = 0
						AddHandler tb.MouseUp, AddressOf OnSelectValue
					End With
				End If

				If value IsNot Nothing AndAlso TypeOf value Is Integer Then
					tb.Value = value
				End If

				edsvc.DropDownControl(tb)
				value = tb.Value
			End If
		End If
		Return value
	End Function

	Private Sub OnSelectValue(ByVal sender As Object, ByVal e As MouseEventArgs)
		edsvc.CloseDropDown()
	End Sub

End Class

أتمنى أن يكون الدرس مفيدا

تم تعديل هذه المشاركة بواسطة GHOST2010 في 20 يوليو 2009 في 08:03 — السبب: إضافة صورة المحرر الجديد

3

إن قلت قال الله قال رسولـه همزوك همز المنكر المتعالي
أو قلت قد قال الصحابة والألـى تبعاً لهم بالقول والأعمال
أو قلت قـال الشافعي وأحمد و أبو حنيفة والإمام الغالي
صدوا عن وحي الإله ودينـه واحتالوا على حرام الله بالإحلال
يا أمةً لعبت بدين نبيها كتلاعب الصبيان في الأوحال
حاشا رسول الله يحكم بالهوى تلك إذاً حكومة الضلال

feed.1.gif

#2

درس رائع و متميز أخي GOST2010 خصوصا و أن الدروس المخصصة لهذا النوع من التطوير قليل و لا يرتقي إلى هذا المستوى...

شكرا

[تحرير]

لا أجد الأداة التي تمكن لي من تقييم الموضوع! المهم بالنسبة لي خمس نجوم *****

تم تعديل هذه المشاركة بواسطة محمد رضى في 19 يوليو 2009 في 16:54

#3

شكرا أخى محمد

تقييم الموضوع موجود فى أعلى الصفحة على اليسار بجوار اسم الموضوع :D :D

قمت بالتقييم نيابة عنك :D :D

تم تعديل هذه المشاركة بواسطة GHOST2010 في 20 يوليو 2009 في 07:47 — السبب: أصابنى الحول ,, كتبت يمين بدل يسار

إن قلت قال الله قال رسولـه همزوك همز المنكر المتعالي
أو قلت قد قال الصحابة والألـى تبعاً لهم بالقول والأعمال
أو قلت قـال الشافعي وأحمد و أبو حنيفة والإمام الغالي
صدوا عن وحي الإله ودينـه واحتالوا على حرام الله بالإحلال
يا أمةً لعبت بدين نبيها كتلاعب الصبيان في الأوحال
حاشا رسول الله يحكم بالهوى تلك إذاً حكومة الضلال

feed.1.gif

#4

درس مميز و جميل ينم عن علم غزير و حب نشر العلم كما قال الخ السابق

تقييمي 5 نجوم و نصف من خمسة

−1

<EMBED src=http://www.abdelghafar.com/images/banners/bm2.swf width=486 height=60 type=application/x-shockwave-flash EMBED < menu="false" loop="true" quality="high">

#5

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

استكمالا للدرس سنقوم بإضافة جزء جديد ألا وهو كيفية رسم القيمة

بمعنى أنك لو نظرت إلى الخاصية BackColor ستجد أن اللون يتم رسمه بجوار إسمه كما فى الصورة

post-47088-1248331394_thumb.jpg

هل تريد عمل ذلك فى أدواتك الخاصة؟؟

إليك الطريقة ,,

بسم الله نبدأ ,,

قم بفتح المشروع الذى أنشأناه سابقا فى أول درس

قم بإضافة هذا الكود

	Public Enum VerticalDirections
		Up
		Down
	End Enum

	Private _dir As VerticalDirections

	Public Property Direction() As VerticalDirections
		Get
			Return _dir
		End Get
		Set(ByVal value As VerticalDirections)
			_dir = value
		End Set
	End Property

قمنا بكتابة خاصية جديدة من النوع VerticalDirections والذى يحتوى على قيمتين فقط هما Up , Down

بما أن الخاصية من نوع Enum فإن المحرر الافتراضى لها سيكون على شكل ComboBox

لن نعدل عليه شئ إلا أننا سنقوم فقط برسم صورة للاتجاه المحدد

تابع معى وستفهم ما أريد أن أوصله له

من نافذة خصائص المشروع قم بفتح التبويب Resources ثم قم بإضافة صورتين واحدة باسم up والثانية باسم down

بعد هذه الخطوة بقى علينا أن نكتب محرر الخاصية

المحرر سيكون الكود المبدئى له بهذا الشكل

Imports System.Drawing.Design
Imports System.Windows.Forms.Design

Public Class DirectionEditor
	Inherits UITypeEditor

End Class

أول شئ يجب أن نقوم به هو أن نخبر المترجم أنه يمكن رسم قيمة الخاصية التى سيعمل عليها المحرر

يتم ذلك من خلال الطريقة GetPaintValueSupported وهى من النوع Boolean

فى حالتنا سنجعلها تعود بالقيمة True حتى نتمكن من الرسم

	Public Overrides Function GetPaintValueSupported(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
		Return True
	End Function

الآن يمكننا الرسم بكل بساطة من خلال الإجراء PaintValue

Public Overrides Sub PaintValue(ByVal e As System.Drawing.Design.PaintValueEventArgs)
		MyBase.PaintValue(e)
		Dim bmp As Bitmap
		If CType(e.Value, MyCustomControl.VerticalDirections) = MyCustomControl.VerticalDirections.Up Then
			bmp = My.Resources.up.ToBitmap
		Else
			bmp = My.Resources.down.ToBitmap
		End If
		e.Graphics.DrawImage(bmp, e.Bounds)
	End Sub

قمنا بتعريف كائن من نوع Bitmap والذى سيحمل الصورة التى سنقوم برسمها

ثم نتأكد من القيمة الحالية التى سيتم رسمها إذا كانت MyCustomControl.VerticalDirections.Up

فإن الكائن سيشير إلى الصورة up وإذا كان MyCustomControl.VerticalDirections.Down

فإن الكائن سيشير إلى الصورة down

ملحوظة: قمت باستخدام الوظيفة ToBitmap لأننى قمت بإضافة أيكونات وليس صور

بعد ذلك نستدعى الإجراء DrawImage التايع للكائن e.Graphics وهو الكائن المسئول عن عملية الرسم

إنتهينا من عملية الرسم

بقى علينا أن نخبر المترجم أن هذا هو محرر الخاصية Direction

كما فعلنا فى المثال الأول

قم بكتابة الخاصية بهذا الشكل

	<Editor(GetType(DirectionEditor), GetType(UITypeEditor))> _
	Public Property Direction() As VerticalDirections
		Get
			Return _dir
		End Get
		Set(ByVal value As VerticalDirections)
			_dir = value
		End Set
	End Property

الآن قم ببناء المشروع ثم اذهب إلى الخاصية Direction وحاول تغيير قيمتها

ستظهر لك بهذا الشكل

post-47088-1248332170_thumb.jpg

--------------------------------

الكود النهائى للمحرر

Imports System.Drawing.Design
Imports System.Windows.Forms.Design

Public Class DirectionEditor
	Inherits UITypeEditor

	Public Overrides Function GetPaintValueSupported(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
		Return True
	End Function

	Public Overrides Sub PaintValue(ByVal e As System.Drawing.Design.PaintValueEventArgs)
		MyBase.PaintValue(e)
		Dim bmp As Bitmap
		If CType(e.Value, MyCustomControl.VerticalDirections) = MyCustomControl.VerticalDirections.Up Then
			bmp = My.Resources.up.ToBitmap
		Else
			bmp = My.Resources.down.ToBitmap
		End If
		e.Graphics.DrawImage(bmp, e.Bounds)
	End Sub

End Class
1

إن قلت قال الله قال رسولـه همزوك همز المنكر المتعالي
أو قلت قد قال الصحابة والألـى تبعاً لهم بالقول والأعمال
أو قلت قـال الشافعي وأحمد و أبو حنيفة والإمام الغالي
صدوا عن وحي الإله ودينـه واحتالوا على حرام الله بالإحلال
يا أمةً لعبت بدين نبيها كتلاعب الصبيان في الأوحال
حاشا رسول الله يحكم بالهوى تلك إذاً حكومة الضلال

feed.1.gif

#6

شكرا أخي GHOST2010 على الإضافة القيمة...

#7

شكرا

شكرا شكرا شكرا شكرا شكرا شكرا شكرا

شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا

شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا

شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا

شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا شكرا

يعطيك العافيه وسلامه

مواضيع مشابهة