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

الواجهه Iextenderprovider الدرس الأول

بدأه C++er في 18 أغسطس 2009 · 4 رد · 2,323 مشاهدة · في قسم الدروس والمواضيع المتميزة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

اثناء عملى ببرامج قواعد البيانات و التى كانت فى الأغلب Disconnected mode كان امامى اختيار من اثنين إما ان اتبع منهجية SE فى تصنيع البرمجيات (و هذا ما يرفضه رؤسائى) و اما ان اقوم بعمل بعض الأدوات التى تتيح لى انشاء جمل Insert و Update و Delete بشكل ديناميكى.

فى الواقع الأمر لم يكن بالهين و لكنى اثناء بحثى لاحظت اداه مثل ToolTip حيث تقوم بإضافة خصائص لكل الأدوات الأخرى و جائتنى الفكره لماذا لا اقوم بعمل اداه تضع مجموعه من الخصائص لكل الأدوات الأخرى و على حسب نوع الأداه بمعنى الأداه نفسها ستحتوى على الخاصيه TableName و هو اسم الجدول الذى سأقوم بالحفظ داخله اما بالنسبه للادوات الأخرى فهى اما ان تكون TextBox و فى هذه الحاله سأضيف الخاصيه FieldName و التى تعبر عن اسم الحقل الذى سأضيف قيمة الـ TextBox داخله و طبعا القيمه ستأتى من الخاصيه Text بالنسبه لأدوات اخرى مثل ListBox سأقوم بإضافة الخاصيه FieldName و هو المكان الذى سيتم الحفظ به داخل الجدول و لكن المشكله انى سأحتاج لـ 3 خصائص اخر الـ Lان الـ ListBox تحتاج لإسم الجدول لتملء منه البيانات التى تظهر فيها و ايضا اسم الحقل الذى ستكون قيمته هى التى ظاهره امام العميل و اسم الحقل الذى سيتم حفظ قيمته داخل الجدول الخاص بالأداه.

ملحوظه :

1 - فى حال عدم فهمك ايا مما سبق لا تقلق فسأقوم بالتفصيل بعد قليل.

2 - سأقوم بإستخدام اللفظين عنصر و خاصيه ليدلوا على خاصيه.

3 - لن اقوم بالتعامل مع قواعد البيانات و لكنى احببت وضع الفكره حتى نكون على اتصال فكرى داخل المثال.

الأداه ToolTip تقوم بتضمين الواجهه IExtenderProvider و التى تتيح لك اضافة خصائص لادوات اخرى.

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

- ماهى IExtenderProvider و كيف تعمل.

- كيف تصنع اداه تدعم IExtenderProvider.

فى هذا الدرس سيتم اضافة خصائص لاداة الـ TextBox فقط.

ماهى IExtenderProvider و كيف تعمل

الـ IExtenderProvider تأخذ الشكل التالى

Public Interface IExtenderProvider
	Function CanExtend(ByVal extendee As Object) As Boolean
End Interface

هذه الواجهه هى واجهه خاصه بالـ Desgin-Time لـ FormsDesigner حيث يقوم الـ FormsDesigner بإستدعاء الداله CanExtend لكل الأداوت الموجوده على أى ContainerControl فإذا عادت الداله بالقيمه True يتم إضافة عنصر جديد (لن اقول خاصيه و ستعرف لماذا) داخل الـ PropertyGrid لهذه الأداه.

كيف تصنع اداه تدعم IExtenderProvider

اولا ماهى الخاصيه : الخاصيه Property هى عباره عن دالتين احداهما تقوم بوضع قيمه فى مكان ما و الأخرى تقوم بإحضار هذه القيمه مكان ما (فى حالتنا هذه من نفس المكان)، بإفتراض ان الـ VB لا يدعم الخصائص لذا يمكن تعريف البديل لها كالتالى

private m_age as Integer

Public Sub setAge(ByVal age as Integer)
   m_age = age
End Sub

Public Function getAge() as Integer
   Return m_age
End Function

السابق هو فعليا تعريف لما نسميه خاصيه حيث انك اذا قمت بفتح برنامج Reflector و قمت برؤية الكود الخاص بالخاصيه Text الخاصه بـ TextBox ستجدها شبيها بالسابق.

فى هذا الجزء سنقوم بعمل اداه من نوع Component و هذا النوع من الأدوات لا يظهر على الـ UI مثله مثل Timer او الـ ToolTip ايضا لا يمكنك الوصول له عن طريق الخاصيه Controls الموجوده بالـ ContainerControl و انما تصل له عن طريق الحقل components و الذى يقوم الـ FormsDesigner بإنشائه عوضا عنك و يقوم بوضعه داخل ملف اسمه يأخذ الشكل التالى XX.Designer.vb

يمكنك انشاء Component عن طريق الكود التالى

Imports System.ComponentModel

Class MyTool
	 Inherits Component
  .
  .
  .
End Class

و لكن يفضل (او الأفضل) أدراجها من قائمة Project.AddComponent حيث يتم اضافة بعض الأكواد الهامه و الخاصه بالـ Desgin للاداه و قم بتسميتها MyTool.

الأن و بعد إضافتك لها قمت بفتح الكود الخاص بها و اضف هذا السطر قبل تعريف الـ Class

Imports System.ComponentModel

و هذا هو المكان الموجود به الواجهه IExtenderProvider بعد ذلك قم بعمل تضمين للواجهه IExtenderProvider داخل الـ Class ليصبح شكلها كالتالى:

Imports System.ComponentModel

Public Class MyTool
	Implements IExtenderProvider

	Public Function CanExtend(ByVal extendee As Object) As Boolean Implements IExtenderProvider.CanExtend

	End Function
End Class

و حيث ان هذه الاداه موجهه للتعامل مع TextBox فقط ستصبح الداله CanExtend كالتالى:

Public Function CanExtend(ByVal extendee As Object) As Boolean Implements IExtenderProvider.CanExtend
	If TypeOf extendee Is TextBox Then
		Return True
	End If
End Function

قلنا فى السابق ان الأداه ستحتوى على خاصيه و هى TableName و الذى سيتم الحفظ داخله و ايضا الأداه ستقوم بإضافة الخاصيه FieldName داخل الاداوت التى ستدعمها MyTool و فى حالتنا هذه TextBox فقط.

بالنسبه للخاصيه TableName ستكون كالتالى

	Private mTableName As String
	Public Property TableName() As String
		Get
			Return mTableName
		End Get
		Set(ByVal value As String)
			mTableName = value
		End Set
	End Property

اما بالنسبه للخاصيه FieldName فلابد من اعلام الـ FormsDesginer ان هذه الخاصيه هى المراد وضعها لكل الـ TextBoxes، و لتقوم بفعل هذا يوفر لنا FormsDesigner الـ ProvidePropertyAttribute و التى تطلب منك معاملين اولهما اسم الخاصيه و ثانيهما نوع الاداه التى سيتم اضافه هذه الخاصيه لها و يتم احضار نوع الاداه بإستخدام GetType.

ملحوظه : سنقوم بتغيير اسم الخاصيه FieldName إلى ZFieldName و ساقوم بإعلامك السبب بعد قليل

لذا يصبح شكل MyTool كالتالى

<ProvideProperty("ZFieldName", GetType(TextBox))> _
Public Class MyTool
	Implements IExtenderProvider
   .
   .
   .
End Class

الأن و قد عرف الـ Designer اسم الخاصيه كيف سنقوم بتضمينها داخل اداتنا، فى الواقع سيتم تضمينها بإسلوب الدالتين و ليس بإسلوب الخصائص المعتاده و السبب فى ذلك لا اعلمه حقيقة و لكن وثائق الـ MSDN تقول انه بالنسبه لهذه الخاصيه سيتم تضمينها على شكل دالتين احداهما تبدء بـ Set و هى تستخدم فى وضع القيمه داخل الخاصيه و الأخرى تبدء بـ Get لاحظ ان الكلمتين لابد ان يكونوا بهذا الشكل و الا لن تعمل الخاصيه (لن تظهر :blink: ).

Public Sub SetZFieldName(ByVal ctl As TextBox, ByVal value As String)

End Sub

Public Function GetZFieldName(ByVal ctl As TextBox) As String

End Function

فى كل الأحوال دالة الـ Set دائما تأخذ معاملين اولهما الأداه التى سيتم وضع الخاصيه لها ثانيهما القيمه التى تم وضعها للأداه و فى حالتنا هذه المعامل الأول هو TextBox اما المعامل الثانى فهو اسم الحقل الذى سيتم الحفظ به و طبعا هو نص

بالنسبه للداله Get فتأخذ معامل واحد فقط هو الاداه التى سيتم إحضار قيمة الخاصيه منها و تعود بالقيمه نفسها و فى حالتنا هذه الكائن المدخل هو الـ TextBox اما القيمه المعاده هى اسم الحقل.

الأن و قد عرفنا شكل الدالتين المفترض كى تقوم الدالتين بعملهم لابد من تخزين القيم فى مكان ما حتى نستطيع استرجاعها فى وقت لاحق. انا استخدم Generic Dictionary لحفظ القيم حيث يكون اسم الاداه هو الـ Key و القيمه هى الـ value و حيث ان الإثنان نصوص لذا يكون الـ Dictionary من نوع نص.

	Private mData As New Dictionary(Of String, String)

	Public Function GetZFieldName(ByVal ctl As TextBox) As String
		If Not mData.ContainsKey(ctl.Name) Then
			Return String.Empty
		End If

		Return mData.Item(ctl.Name)
	End Function

	Public Sub SetZFieldName(ByVal ctl As TextBox, ByVal value As String)
		If mData.ContainsKey(ctl.Name) Then
			If value.Trim = String.Empty Then
				mData.Remove(ctl.Name)
			Else
				mData.Item(ctl.Name) = value
			End If
		Else
			If value.Trim = String.Empty Then Return
			If ctl.Name = String.Empty Then Return
			mData.Add(ctl.Name, value)
		End If

	End Sub

فى البدايه قمنا بتعريف الكائن mData و الذى سيحتوى على القيم و بعدها قمنا بتعريف الداله GetZFieldName فى الواقع المفترض ان يتم شرحها بعد الداله SetZFieldName و لكنى احبذ شرحها فى البدايه.

فى بدايه الداله GetZFieldName نتحقق من وجود اسم الاداه داخل mData فإن كان غير موجود نرعود بنص فارغ و غير ذلك نعود بقيمته من mData.

فى بدايه الداله SetZFieldName نقوم بالتحقق من وجود اسم الأداه فإن كانت موجوده نتحقق من ان القيمه المدخله ليست فارغه فإن كان اسم الاداه موجود و القيمه المدخله فارغه سنقوم بحذف اسم الاداه من mData و هذا بسبب انك عندما تجعل قيمة خاصيه ما فارغه فهذا يعنى حذفك للقيمه.

اما إن كان اسم الاداه غير موجود داخل mData فنقوم بالتحقق من ان القيمه المدخله ليست فارغه و ان اسم الأداه نفسها ليس فارغ بعدها نقوم بإضافة اسم الاداه و القيمه لـ mData.

الأداه الأن جاهزه للعمل فقط قم بعمل Build للمشروع و ستظهر داخل Toolbox.

يتم لتعامل مع هذه الخصائص وقت تشغيل البرنامج من داخل الأداه نفسها عن طريق الدالتين SetZFieldName و GetZFieldName.

بالنسبه لتغييرى لإسم الخاصيه من FieldName إلى ZFieldName السبب هو ان الخاصيه الخاصه بإسم الاداه Name ترتيبها الأبجدى يأتى بعد FieldName و بالتالى عندما يقوم FormsDesginer بعمل الكود الخاص بوضع القيمه داخل الاداه سيقوم بوضع تعريف SetFieldName قبل اسم الأداه داخل الخاصيه Name و حيث اننا نمرر اسم الأداه للداله SetFieldName فبالتالى سيكون دائما فارغ لهذا قمت بجعل اسم الخاصيه ZFieldName حتى ياتى تريبها داخل كود الـ Designer بعد الخاصيه Name.

IExtenderProviderEx.rar

و الله ولى التوفيق

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 19 أغسطس 2009 في 06:50

مدونتي: C++ Tips and Tricks

#2

جميل أخي محمد, درس رائع وفكرة أروع.

شكرا جزيلا لمشاركتنا بهذه الفكرة و بارك الله لك في علمك و عملك.

تحياتي...

#3

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

:cry: :mad: :stop: post-52996-1243599601.gifpost-52996-1243599597.gif

ده كان أحد الأسئلة اللى انا محضرها لكن انت حرقته ,, لكن درس رائع وجميل جدا :blush:

سيتم نقل الدرس بعد يومين إلى قسم الدروس المتميزة إن شاء الله

تم تعديل هذه المشاركة بواسطة GHOST2010 في 19 أغسطس 2009 في 07:39

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

feed.1.gif

#4

معلش بقى خيرها فى غيرها يعم Ghost

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

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#5

شكرا

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

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

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

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

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

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

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