05-10-12, 06:54 PM
كاتب الموضوع : silverlight
اخواني الكرامفي سؤال لأحد الزملاء بالموقع عن كيفية إظهار Drives الموجودة علي الهارد ديسك داخل كونترول مثل Listview وإضافة أيقونات لها للأسف كنت مشغول ولم استطيع ان أرد عليه بالشكل المناسب ومن اجل ذلك أردت ان أرد عليه بهذا الموضوع لكي نستفيد جميعا
في الواقع إن استخدام الكونترول بشكل عام يحدده احتياجات البرنامج الذي نصممه مثلا عندما أريد أن اعرض جميع Drives الموجوده داخل الكمبيوتر من الأفضل ان أختار الكونترول المناسب لمثل هذه العملية عموما انا لن أناقش هنا كيفية التخطيط للبرامج أو كيفية تحديد الكونترول المناسب للكود المناسب فتخطيط البرامح علم كبير جدا الأن
لكن مثلا عندما أريد ان استعرض Drives الموجوده علي الكمبيوتر من الأفضل ان اختار لذلك ComboBox لأن صفاته Properties الخاصة بهذا الكونترول مهيأة لمثل هذا الهدف عموما هذا رأي شخصي مش أكتر
الحقيقة الجزء الي يهمني هنا أن اتحدث عنه هو كيفية إضافة أيقونات مناسبة الي الكومبو بوكس مثلا او إلي أي كونترول اخر فعملية إضافة أسماء Drives الي الكومبوبوكس أو حتي أي كونترول أخر ليست هي الجزء الهام في الامر فهي امر سهل يعلمه الجميع
كما يعلم الجميع إن أي كونترول من الممكن تغيير شكله وتغيير صفاته وأيضا يمكن بناؤه كاملا لناخذ مثالا علي ذلك الكومبو بوكس ومن اجل ان لا أطيل عليكم ٍادخل مباشرة في الموضوع
بعض الكونترول الموجوده بداخل الفيجوال استوديو بها خاصية OwnerDraw وهي خاصية تسمح للمبرمج بتطوير الكونترول والتغيير فيه بما يناسب البرنامج الذي يصممه ومثال علي ذلك الكومبو بوكس مثلا
كيف نستفيد من هذه الخاصية لنعيد رسم الكومبوبوكس ومن ثم نضيف له بعض الأيقونات لكي يظهر بشكل أفضل
اولا نقوم بفتح مشروع windowforms عادي جدا
أولا: نضيف الي المشروع كلاس جديد ولنطلق عليه مثلا DirComboBox
ثانيا: من داخل هذا الكلاس نقوم بعمل Inherits لكومبوبوكس
ثالثا: نضيف له بعض Items ولتكن مثلا Drives الموجوده علي الهارد ديسك
الجزء التالي من الكود يوضح الخطوات الثلاث السابقة في واقع الأمر فيه شئ قمت باستخدامه هنا وهو كلاس مهم جدا ربما نتحدث عنه في مقال اخر وهو LicenseManager ولقد قمت باستخدامه لتحديد ان عملية إضافة Items الي الكومبوبوكس يجب ان تتم في حالة RunTime Modes أي أثناء تشغيل البرنامج فقط لا غير
كود :
Imports System.ComponentModel
Imports System.Collections.ObjectModel
Imports System.IO
Public Class DirComboBox
Inherits ComboBox
Public Sub New()
MyBase.DropDownStyle = ComboBoxStyle.DropDownList
MyBase.DrawMode = Windows.Forms.DrawMode.OwnerDrawFixed
MyBase.ItemHeight = 18
Dim Drives As ReadOnlyCollection(Of DriveInfo)
If LicenseManager.UsageMode = LicenseUsageMode.Runtime Then
Drives = My.Computer.FileSystem.Drives
For Each Drive As DriveInfo In Drives
MyBase.Items.Add(Drive)
Next
MyBase.SelectedIndex = -1
End If
End Sub
End Class
رابعا: نقوم بعمل Overrides كلاس sub الموجودة داخل الكومبوبوكس وهو Sub OnDrawItem
هنا سنتوقف قليلا لتوضيح الفكره
الفكرة ببساطة تعتمد علي إضافة بعض Resources للمشروع تمثل بعض الأيقونات التي سوف تظهر بجانب كل Drive موجود داخل الكمبيوتر مثل الهارد ديسك او CD/DVD وغيرهم
وبعد ان نقوم بتعريف الايقونات نقوم برسمها داخل الكومبوبوكس مع ربط كل أيقونة بكل Drive يناسبها عن طريق استخدام Select Case وايضا نقوم برسم Text وهو هنا سيكون اسماء Drives بالإضافة الي VolumeLabel
كما تلاحظون كل شئ تم باستخدام +GDI وأعتقد الدوت نت جعل الأشياء افضل ووفر الوقت في حاجات كتيير لكن المهم نعرف أين وكيف وماذا نستخدم لكي نصل الي ما نريد
نفس الفكرة ممكن استخدامها مع Listview ايضا مع بعض التغييرات البسيطة
الكود التالي يوضح الكود كاملا واعتقد انه بسيط ومش محتاج تفسيرات كثيرة عموما لمن يريد الاستفسار يمكنه ان يسال
كود :
Imports System.ComponentModel
Imports System.Collections.ObjectModel
Imports System.IO
Imports System.Windows.Forms
Imports System.Drawing
Public Class DirComboBox
Inherits ComboBox
Public Sub New()
MyBase.DropDownStyle = ComboBoxStyle.DropDownList
MyBase.DrawMode = Windows.Forms.DrawMode.OwnerDrawFixed
MyBase.ItemHeight = 18
Dim Drives As ReadOnlyCollection(Of DriveInfo)
If LicenseManager.UsageMode = LicenseUsageMode.Runtime Then
Drives = My.Computer.FileSystem.Drives
For Each Drive As DriveInfo In Drives
MyBase.Items.Add(Drive)
Next
MyBase.SelectedIndex = -1
End If
End Sub
Protected Overrides Sub OnDrawItem(ByVal e As DrawItemEventArgs)
If e.Index = -1 Then Return
Dim drive As DriveInfo = MyBase.Items(e.Index)
Dim img As Icon
Select Case drive.DriveType
Case DriveType.Fixed
img = My.Resources.Hard_Drive
Case (DriveType.CDRom)
img = My.Resources.DVD_ROM
Case (DriveType.Network)
img = My.Resources.Network
Case (DriveType.Removable)
img = My.Resources.emd
Case DriveType.Ram
img = My.Resources.ram
Case Else
img = My.Resources.UnknownDrive
End Select
Dim imgbox As New Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Height, e.Bounds.Height)
e.DrawBackground()
e.Graphics.DrawIcon(img, imgbox)
img.Dispose()
Dim text As String
text = drive.Name
If drive.IsReady Then
If drive.VolumeLabel IsNot Nothing Then
text = drive.VolumeLabel & " (" & drive.Name & ")"
End If
End If
e.Graphics.DrawString(text, e.Font, New SolidBrush(e.ForeColor), e.Bounds.X + imgbox.Width + 2, e.Bounds.Y)
If e.State = DrawItemState.Focus Then
e.DrawFocusRectangle()
End If
End Sub
End Class
كود :
text = drive.VolumeLabel & " (" & drive.Name & ")" & "
ممكن مثلا تكتبه بالطريقه دي
text = drive.VolumeLabel & " (" & drive.Name & ") " & "VB4Arab"
كود :
e.Graphics.DrawString(text, e.Font, New SolidBrush(e.ForeColor), e.Bounds.X + imgbox.Width + 2, e.Bounds.Y)
مثلا جرب هنا تغير الفونت وتغير الألوان وممكن تسخدم LinearGradientBrush بدلا من solidBrush
جرب مش ها تخسر حاجه
C:\Programfiles\Microsoft visual Studio 9.0\common7
ستجدون ملف مضغوط اسمه VS2008ImageLibrary
ونفس الشئ بالنسبة للفيجوال 2005
C:\Programfiles\Microsoft visual Studio 8.0\common7
ستجدون ملف مضغوط اسمه VS2005ImageLibrary
قم بفك الملفات المضغوطه ستجدون بها الكثير من الايقونات وملفات animations وغيرهم حيث يمكن استخدامها داخل برامجك
بالتوفيق
أخوكم عمر