السلام عليكــم ورحمـة الله وبركاتــه ،،
بعد أن تعلمنا فى هذا الدرس كيفية استخدام الفئة UITypeEditor لتصميم محرر خصائص سنتعلم اليوم كيفية إنشاء خاصية من النوع Structure أو من نوع Class وإمكانية تحريرها فى نافذة الخصائص
لفهم ما أقصد قم بإنشاء فئة جديدة بهذا الكود
Imports System.ComponentModel Public Class MyCustomControl Inherits UserControl Public Structure MyStruct Private _x, _y As Integer Public Property X() As Integer Get Return _x End Get Set(ByVal value As Integer) _x = value End Set End Property Public Property Y() As Integer Get Return _y End Get Set(ByVal value As Integer) _y = value End Set End Property End Structure Private _struct As New MyStruct Public Property Struct() As MyStruct Get Return _struct End Get Set(ByVal value As MyStruct) _struct = value End Set End Property End Class
قمنا بإنشاء تركيب Structure باسم MyStruct يحتوى على خاصيتين هما X , Y من النوع Integer
ثم أنشأنا خاصية تحمل نوع هذا التركيب وهى الخاصية Struct
قم ببناء المشروع ثم ضع هذه الأداة على الفورم واذهب إلى الخاصية Struct وحاول تغيير قيمتها
ماذا لاحظت؟؟
نعم ,, لن تستطيع تغيير قيمتها وستظهر بهذا الشكل
إذاً كيف نجعل مستخدم الأداة قادرا على تغيير قيمة الخاصية مثل الخاصية Font , Location , Size
لعلك الآن فهمت ما أقصد
الآن قم بإضافة فئة جديدة باسم MyStructConverter وسيكون الكود المبدئى لها بهذا الشكل
Imports System.ComponentModel Public Class MyStructConverter Inherits ExpandableObjectConverter End Class
هل لاحظت السطر الثالث؟؟
نعم ,, الفئة التى قمنا بوراثتها هى المسئولة عما نريد أن نفعله
إذهب إلى الفئة MyCustomControl وغير كود الخاصية Struct لتكون بهذا الشكل
<TypeConverter(GetType(MyStructConverter))> _ Public Property Struct() As MyStruct Get Return _struct End Get Set(ByVal value As MyStruct) _struct = value End Set End Property
قم بإعادة بناء المشروع واذهب إلى الفورم وحاول تغيير قيمة الخاصية
ماذا لاحظت؟؟
نعم ,, يمكنك الآن تحرير الخاصية بكل سهولة وستتحول الخاصية إلى هذا الشكل
لكن انتظر ,, ليس هذا كل شئ
انظر مثلا إلى الخاصية Size ستجد أن قيمتها تظهر بهذا الشكل x;y
أما فى حالتنا فستظر القيمة بالشكل WindowsApplication1.MyCustomControl+MyStruct ونحن لا نريد هذا ,, نريدها أن تظهر مثل الخاصية Size
أعذرونى على الإطالة وعلى الشرح الممل :blink: :blink:
اذهب الآن إلى الفئة MyStructConverter وسنقوم بكتابة بعض الأكواد الممتعة :D :D
الفئة التى قمنا بوراثتها تحتوى على 4 وظائف مهمة جدا وهى التى سيتم العمل عليها
CanConvertTo : يتم استدعائها عندما تحول أنت كمبرمج للأداة قيمة الخاصية إلى الشكل x;y فتحدد هل يمكن تحويل هذا النوع إلى النوع String أم لا
CanConvertFrom : يتم استدعائها عندما تكتب القيمة بيديك ,, مثلا إذا ذهبت إلى الخاصية Size وكتبت 30;60 يتم استدعاء هذه الوظيفة لتحدد هل يمكن تحويل القيمة التى كتبتها إلى النوع Size أم لا
ConvertTo : وهذه لتحويل قيمة الخاصية إلى النوع String
ConvertFrom : وهذه لتحويل القيمة التى كتبها المستخدم إلى النوع MyStruct
قد تكون هذه الوظائف غير واضحة من الشرح لكن بعد تطبيق المثال ستتضح لك بإذن الله
الوظيفة الأولى : CanConvertTo
بما أننا سنحول القيمة لتظهر على شكل String فيجب أن نتحقق أن النوع المطلوب التحويل إليه هو String
Public Overrides Function CanConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal destinationType As System.Type) As Boolean If destinationType Is GetType(String) Then Return True End If Return MyBase.CanConvertTo(context, destinationType) End Function
المعامل destinationType يحمل النوع المراد التحويل منه
الوظيفة الثانية : CanConvertFrom
بالطبع القيمة التى سيكتبها المستخدم بيديه ستكون من النوع String
سيكون الكود بهذا الشكل
Public Overrides Function CanConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal sourceType As System.Type) As Boolean If sourceType Is GetType(String) Then Return True End If Return MyBase.CanConvertFrom(context, sourceType) End Function
حيث أن المعامل sourceType يحمل النوع المراد التحويل منه فقمنا بالتأكد من هذا النوع إذا كان String فيمكن التحويل منه ولذلك أعدنا القيمة True
الآن ندخل على الوظيفتين الأهم
علينا الآن أن نعالج عمليات التحويل من وإلى String
نبدأ بالتحويل إلى String
الوظيفة الثالثة : ConvertTo
نريد تحويل قيمة الخاصية التى هى من النوع MyStruct لقيمة من النوع String تظهر بالشكل x;y
Public Overrides Function ConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As System.Type) As Object If destinationType Is GetType(String) AndAlso value IsNot Nothing Then Dim st As MyCustomControl.MyStruct = CType(value, MyCustomControl.MyStruct) Return st.X & ";" & st.Y End If Return MyBase.ConvertTo(context, culture, value, destinationType) End Function
بعد التأكد من أن النوع المراد التحويل إليه هو String وأن المعامل Value والذى يحمل القيمة المراد تحويلها يحتوى فعلا على قيمة قمنا بإعادة قيمة من النوع String تحمل الشكل المطلوب x;y
الآن لو كتب المستخدم فى خانة قيمة الخاصية 50;100 ,, كيف سنحول هذه القيمة إلى النوع MyStruct ??
هذا هو ما تفعله الوظيفة الرابعة
الوظيفة الرابعة : ConvertFrom
كما هو واضح من الشرح السابق أن المتغير النصى x;y يحتوى على قيم الخصائص X , Y داخل التركيب MyStruct ويفصل بينها بالرمز ; لذلك سنقوم بتجزئة القيمة بدلالة هذا الرمز لنحصل على مصفوفة تحتوى على القيمتين X , Y ثم بعد ذلك نعرف متغير جديد من النوع MyStruct ونسند هذه القيم إلى الخصائص داخل هذا المتغير ثم نعيد هذا المتغير كقيمة عائدة من الوظيفة كما هو موضح فى الكود التالى
Public Overrides Function ConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object) As Object
If TypeOf value Is String Then
Dim st As New MyCustomControl.MyStruct
Dim values() As String = value.ToString.Split(";")
st.X = values(0)
st.Y = values(1)
Return st
End If
Return MyBase.ConvertFrom(context, culture, value)
End Functionانتهى الكود إلى هنا ,, أعد بناء المشروع واذهب إلى الخاصية وحاول تغيير قيمتها وسترى نتيجة عملك
سيكون الشكل النهائى لها
وهذا هو الكود النهائى للفئة MyStructConverter
Imports System.ComponentModel
Public Class MyStructConverter
Inherits ExpandableObjectConverter
Public Overrides Function CanConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal destinationType As System.Type) As Boolean
If destinationType Is GetType(String) Then
Return True
End If
Return MyBase.CanConvertTo(context, destinationType)
End Function
Public Overrides Function CanConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal sourceType As System.Type) As Boolean
If sourceType Is GetType(String) Then
Return True
End If
Return MyBase.CanConvertFrom(context, sourceType)
End Function
Public Overrides Function ConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As System.Type) As Object
If destinationType Is GetType(String) AndAlso value IsNot Nothing Then
Dim st As MyCustomControl.MyStruct = CType(value, MyCustomControl.MyStruct)
Return st.X & ";" & st.Y
End If
Return MyBase.ConvertTo(context, culture, value, destinationType)
End Function
Public Overrides Function ConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object) As Object
If TypeOf value Is String Then
Dim st As New MyCustomControl.MyStruct
Dim values() As String = value.ToString.Split(";")
st.X = values(0)
st.Y = values(1)
Return st
End If
Return MyBase.ConvertFrom(context, culture, value)
End Function
End Classأعتذر مرة أخرى عن الشرح السئ لكن إذا كان هناك شئ مبهم فلا تترددوا فى السؤال ولا تنسونى من الدعاء بظهر الغيب

