السلام عليكم
الأدوات المخصصة لرسم عناصر القائمة المنسدلة ComboBox Items
صورة للمشروع الثاني ( متوسط المستوى)
يهدف هذا الدرس إلى تعلم كيفية رسم مواد أو عناصر القائمة المنسدلة
بحيث نضيف لها صور أو نصوص عن طريق الرسم .
مالذي يتعين علينا القيام به قبل رسم مواد القائمة .
1. لابد أن نجعل الخاصية الـ DrawMode في الـ ComboBox تساوي OwnerDrawFixed
2. لابد أن نجعل هيئة القائمة style على النمط DropDownList
3. لابد أن نضيف قيم للقائمة قبل رسمها .
4. لابد أن نستخدم الحدث DrawItem لرسم مواد القائمة.
الشرح
OwnerDrawFixed تعني أن العناصر التي سترسم في القائمة المنسدلة تكون
بنفس الطول و العرض فإذا كنت لا ترغب في ذلك فجعل الخاصية تساوي
القيمة OwnerDrawVariable حيث تقوم بتغيير حجم قيم العناصر
وفقاً لطول المادة أو عرضها في حدث مقياس أو قياس المادة MeasureItem .
فكما تعلموان أن Variable تعني متغير فهو OwnerDrawVariable متغير و متفاوت الطول والعرض
معلومة : القيمة OwnerDrawVariable هي القيمة الوحيدة التي تقوم بتفعيل الحدث MeasureItem فقط.
ثم الخطوة الثانية نعين أن القائمة غير قابلة لإضافة قيم وقت التشغيل
وذلك عن طريق إسناد القيمة DropDownList كهيئة للخاصيةStyle .
في الخطوة الثالثة نضيف قيم للقائمة وفقاً للمشروع مثلاً في المشروع الحالي سنضيف أسماء الالوان.
الخطوة الرابعة والاخيرة الحدث DrawItem يتم تفعيلة fire كل ما تم ظهور عناصر Items القائمة
سواءً كانت منسدلة أو غير منسدلة, بمعنى أخر هذا الحدث مفعل طول الوقت .
كيف نرسم المواد في القائمة .
على اعتبار أنك تعرف أدوات الرسم في GDI+ كمثلاً
القلم Pen و الخط Fontو المستطيل Rectangleو تهيئة القيم النصية StringFormat
الفرشاة ذات المعادلة القيمية لدرجة إنحدار (لونين) LinearGradientBrush و الفرشاة السميكة Solid Brush
و الفرشاة العامة أو العادية Brush .
لرسم المواد في القائمة سنرسم اولاً المستطيل بطول وعرض .
كذلك بالنسبةِ للإحداثيين السيني و الصادي X and Y سيكونان بلا شك بقيمة أقل حتى نبتعد عن حدود القائمة .
ثم بعد رسم المستطيل سنقوم بتعبئته بلونٍ ما وفقاً للقيم المتوفرة في القائمة من حيث الفهرس Index
ثم نقوم برسم مستطيل اسود كحدود للألوان داخل المستطيل
بعدها سنرسم اسم اللون بجانب اللون ,,, .
نبدأ باسم الله
قم بإدراج قائمة منسدلة ComboBox و أعطها الاسم CBoxColors ثم أكتب في حدث التحميل Load Event النصوص البرمجية التالية
'تسريع إظهار النموذج Me.Show() With CBoxColors 'إذا كنت تود برسم عناصر القائمة بشكل متساوي كطول وعرض 'OwnerDrawFixed إجعل خاصية نوع الرسم يساوي القيمة التالية .DrawMode = DrawMode.OwnerDrawFixed 'كشرط لرسم عناصر القائمة أن نضع هيئة القائمة على القيمة '(DropDownList) predefind List .DropDownStyle = ComboBoxStyle.DropDownList 'إمنع رسم القائمة .BeginUpdate() 'حلقة فيها متغير نقوم بواسطة إضافة اسم اللون في القائمة For Each strKnownColor As String In System.Enum.GetNames _ (GetType(System.Drawing.KnownColor)) 'Enumirations أضف اسماء الالوان المتوفرة في المعد اللوني .Items.Add(Color.FromName(strKnownColor)) Next ' أعد رسم القائمة المنسدلة بعد أضافة كل القيم فيها .EndUpdate() End With
أظن أنها سهله و مُعلق عليها للتوضيح الان قم بإدراج النصوص التالي ستكون في الحدث DrawItem
'ارسم الخلفية مع اللون الإفتراضي الازرق لكل العناصر e.DrawBackground() 'إعطي المستطيل المرسوم داخل القائمة صفة التركيز عليه ' إذا كان في وضع أو حالة رسمه e.DrawFocusRectangle() 'إذا كانت القائمة لا تساوي 1- ارسم مواد القائمة If Not e.Index < 0 Then 'بما أن الألوان ذات أرقام 'سنقوم بإنشاء عنصر لوني يأخذ الرقم وفقاً لفهرسة عناصر القائمة Dim aColor As Color = CType(CBoxColors.Items(e.Index), Color) 'إنشاء مستطيل صغير الحجم لوضعه داخل القائمة Dim Rect As Rectangle = New Rectangle(1, e.Bounds.Top + 2, _ e.Bounds.Height, e.Bounds.Height - 4) 'نصنع فرشاة رسم Dim br As Brush 'إذا تم إختيار إحدى عناصر القائمة والعنصر كان في حالة رسمه If e.State And Windows.Forms.DrawItemState.Selected Then 'نجعل لون الفرشاة أبيض br = Brushes.White Else 'غير ذلك اي أن القائمة منسدلة الوضع سنجعل لون الفرشاة أسود br = Brushes.Black End If 'ارسم المستطيل e.Graphics.DrawRectangle(New Pen(aColor), Rect) 'إملئ المستطيل باللون المناسب e.Graphics.FillRectangle(New SolidBrush(aColor), Rect) ' باعد حدود المستطيل بقيمة 1 بكسل كوحدة قياسية من كِلا الإتجاهين طول وعرض Rect.Inflate(1, 1) 'ارسم حدود المستطيل بالخط الاسود e.Graphics.DrawRectangle(Pens.Black, Rect) 'أكتب اسم اللون بجانب اللون داخل القائمة المنسدلة 'وفقاً لإسماء الالوان e.Graphics.DrawString(aColor.Name, _ CBoxColors.Font, br, e.Bounds.Height + 5, _ ((e.Bounds.Height - CBoxColors.Font.Height) \ 2) + e.Bounds.Top) End If '-- يساوي 1- فإن المترجم سيصل هذا المنطقة Index إذا كان فهرس القائمة ' ثم يخرج من الاجراء بشكل آمن دون حدوث اي مشكلة
نصوص حدث رسم المادة DrawItem
نقوم برسم خلفية القائمة و إعطاء المادة المرسومة صفة التركيز عليها focus
بشرط أن يكون فهرس القائمة Index يساوي سالب واحد -1
غير ذلك سنقوم بالتالي
سنقوم بإنشاء لون وفقاً لفهرسة القائمة ( أسود أبيض أخضر ... إلخ)
ثانياً سنرسم حدود المستطيل ( إحداث سيني X, إحداث صادي Y, عرض Width, طول Height)
ثم ننشأ فرشاة للرسم
ثم نختبر في الشرط هل تم إختيار إحدى عناصر القائمة اي هل القائمة منسدلة كوضع أو حالة.
فهذا الشرط لابد أن يتم عن طريق And وليس AndAlso لسبب واحد فقط
هو أننا نختبر قيمتين لنفس الحالة, فهل هي في اي وضع من الاوضاع مع وضع الاختيار Selected
ففي أي وضع ستكون مثلاً NoFocusRect أو ComboBoxEdit أو NoAccelerator أو غير ذلك
مع بقاء الوضع على حالة الاختيار سيتم تفعيل اللون الابيض .
وبما أننا لم نحدد اي وضع بالضبط فإن AndAlso سيفشل لا محالة لان الشرط غير محدد .
و الذي نريدة و نقصدة من هذا النص هو إذا جاء سهم الفأرة على إحدى قيم القائمة وهي منسدلة أجعل
لون تلك المادة أو بالاحرى لون النص في القائمة باللون الابيض , و كذلك إذا تم إختيارها فنقبضت القائمة
كذلك إجعل لونها هو الابيض غير ذلك أجعل لونها اسود.
ثم نرسم مستطيل ونقوم بتلوينه عن طريق الفرشاة السميكة Solid Brush
ثم نباعد بين المستطيل الحالي بالسابق بقيمة 1 بكسل من حيث الطول و العرض
ثم نرسم حدود المستطيل باللون الاسود لإضافة جمالية على المستطيل
و أخيراً نرسم اسم اللون بجانب المستطيل المُلون بنفس الالون . باستخدام فهرس المصفوفة .
هذا والله أعلم .
كل الامثلة مزودة بالتعليق
إذا تمرست من هذا المشروع سيسهل عليك مشروع إضافة الصور
بالتوفيق أخوتي الكرام .
ملاحظة : المشروع الحالي ليس مشروع و إنما مشروع صاحب الكتاب أم الثاني فهو لي وبلا شك هو لنا جميعاً .
المرجع : كتاب Developing Microsoft .NET controls with Visual Basic .NET
الـ Chapter 2 الصفحة رقم 55 إلى الصفحة 80 .






