کنترل ListView

کنترل ListView به شما امکان نمایش لیستی از آیتم‌ها در نماهای مختلف و اضافه کردن آیکن هایی به هر یک از آنها را می‌دهد. کنترل ListView ترکیبی از ListViewItems که ساختاری تور توری متشکل از سطر و ستون دارد، می‌باشد. هر ListViewItem یک برچسب دارد و هر ListViewItem در ستون اول، یک آیکن در کنارشان وجود دارد. یکی از موارد استفاده‌ی کنترل ListView، نمایش پوشه‌ها و فایل‌ها به کاربر است. در شکل زیر نمایی از این کنترل را مشاهده می‌کنید:
listview-1001
مشاهده می‌کنید که Windows Explorer از یک کنترل ListView برای نمایش فایل‌ها و پوشه‌ها استفاده می‌کند. در مثال بالا از نمای Details استفاده شده است، اگرچه نماهای دیگری مثل Large Icons و Small Icons نیز وجود دارند. در جداول زیر برخی از خواص، متدها، و رویدادهای کنترل ListView را مشاهده می‌کنید:

خاصیت توضیح
Activation مشخص می‌کند که کاربر چگونه می‌تواند یک آیتم را در ListView فعال کند، مقادیر ممکن برای این خاصیت عبارتند از:

  • OneClick : با یک بار کلیک آیتم مورد نظر فعال می‌شود.
  • TwoClick : با دوبار کلیک کردن آیتم مورد نظر فعال می‌شود.
  • Standard : از تنظیمات کامپیوتر استفاده می‌کند.
Alignment نوع چینش آیتم‌ها را مشخص می‌کند. مقادیر ممکن برای این خاصیت عبارتند از :

  • Default : هیچ نوع چینش خاصی بر روی آیتم‌ها اعمال نمی‌گردد.
  • Left : آیتم‌ها را به سمت چپ ListView مرتب می‌کند.
  • Top : آیتم‌ها را به بالای ListView مرتب می‌کند.
  • SnapToGrid : یک شبکه‌ی مخفی درست کرده که آیتم‌ها به آن متصل می‌شوند.
AllowColumnReorder مشخص می‌کند که کاربر می‌تواند با Drag کردن عنوان ستون‌ها آنها را جابه جا کند یا خیر.
AutoArrange وقتی مقدار این خاصیت برابر با True باشد، آیتم‌ها براساس خاصیت Alignment چیده می‌شوند. تأثیر این خاصیت فقط در زمانی که نما (View) در یکی از حالات LargeIcon یا Small Icon باشد دیده می‌شود.
CheckBoxes مشخص می‌کند که یک CheckBox به سمت چپ هر آیتم در نمای Details نمایش داده شود یا خیر.
CheckedIndices مجموعه‌ای از اندیس‌های آیتم‌های تیک خورده را مشخص می‌کند.
CheckedItems مجموعه‌ای از آیتم‌های تیک خورده را مشخص می‌کند.
Columns مجموعه‌ای از ستون‌های ListView را در بر می‌گیرد و به شما اجازه می‌دهد که ستونی را حذف و یا اضافه کنید.
FocusedItem آیتمی که انتخاب شده را در بر می‌گیرد. اگر هیچ آیتمی انتخاب نشده باشد هیچ مقداری را بر نمی‌گرداند.
FullRowSelect مشخص می‌کند که با کلیک بر روی یک آیتم تمام سطر آن انتخاب شود یا خیر.
HeaderStyle حالت نمایش هر ستون را مشخص می‌کند. مقادیر ممکن برای این خاصیت عبارتند از :

  • Clickable : به شما اجازه می‌دهد که مانند یک دکمه بر روی عنوان ستونها کلیک کنید.
  • NonClickable : عنوان ستون هیچ واکنشی به کلیک کردن نشان نمی‌دهد.
  • None : عناوین ستون‌ها را مخفی می‌کند.
HoverSelection مشخص می‌کند که اگر اشاره گر ماوس بر روی یک آیتم برده شد، آن آیتم انتخاب شود یا خیر.
Items مجموعه‌ای از آیتم‌های یک ListView را در بر می‌گیرد.
LabelEdit مشخص می‌کند که کاربر می‌تواند متن یک آیتم را تغییر دهد یا خیر.
LargeImageList یک کنترل ImageList را مشخص می‌کند، که شامل آیکونهایی است که در حالت LargeIcon مورد استفاده قرار می‌گیرند.
MultiSelect مشخص می‌کند که کاربر می‌تواند چند آیتم را با هم انتخاب کند یا خیر.
Scrollable مشخص می‌کند که نوار پیمایش (Scroll) نمایش داده شود یا خیر.
SelectedIndices مجموعه‌ی تمامی اندیس‌های آیتم‌های انتخاب شده را در بر می‌گیرد.
SelectedItems مجموعه‌ی آیتم‌های انتخاب شده را در بر می‌گیرد.
ShowItemToolTips مشخص می‌کند که ToolTip مربوط به هر آیتم نمایش داده شود یا خیر.
ToolTip : توضيحاتي که با نگه داشتن ماوس روي آیتم نمايان می‌شود.
SmallImageList یک کنترل ImageList را مشخص می‌کند.، که شامل آیکونهایی است که در حالت SmallView مورد استفاده قرار می‌گیرند.
Sorting به کنترل ListView اجازه می‌دهد که آیتم‌های خود را با استفاده از مقادیر زیر مرتب کند:

  • Ascending : آیتم‌ها را بر اساس سیر صعودی مرتب می‌کند.
  • Descending : آیتم‌ها را بر اساس سیر نزولی مرتب می‌کند.
  • None : آیتم‌ها مرتب نمی‌کند.
TopItem بالاترین آیتم در کنترل ListView را در خود جای می‌دهد.
View مشخص می‌کند که آیتم‌ها چگونه نمایش داده شوند، مقادیر ممکن برای این خاصیت عبارتند از :

  • Large Icon : آیتم‌ها با استفاده از یک آیکن 32*32 و یک برچسب نمایش داده می‌شوند.
  • Small Icon : آیتم‌ها با استفاده از یک آیکن 16*16 و یک برچسب نمایش داده می‌شوند.
  • List : آیتم‌ها را به شکل لیستی از آیکن ها و برچسب‌ها نمایش می‌دهد.
  • Details : تعدادی ستون را نمایش می‌دهد که در آنها اطلاعاتی در مورد هر آیتم قرار می‌گیرد.
  • Tile : یک آیکن بزرگ و یک برچسب به همراه یک توضیح کوتاه در زیر آنها برای هم آیتم نمایش می‌دهد.

برخی از متدهای این کنترل در جدول زیر ذکر شده‌اند :

متد توضیح
Clear() این متد همه‌ی آیتم‌های کنترل ListView را حذف می‌کند.
EnsureVisible() به صورت اتوماتیک ListView را پیمایش می‌کند، بنابراین آیتم و اندیسی که شما مشخص کرده‌اید نمایش داده خواهد شد.
GetItemsAt() تمامی آیتم‌هایی که در یک مختصات (x,y) خاص وجود دارند را می‌گیرد.

رویدادهای ListView :

رویداد توضیح
AfterLabelEdit بعد از اینکه برچسب یک آیتم ویرایش شد این رویداد رخ می‌دهد.
BeforeLabelEdit قبل از اینکه برچسب یک آیتم ویرایش شود این رویداد رخ می‌دهد.
ColumnClick زمانی که کاربر بر روی یک ستون کلیک کند این رویداد رخ می‌دهد.
ItemActivate زمانی که کاربر یک آیتم را انتخاب و یا فعال کند این رویداد رخ می‌دهد.

حال که شما با خواص، متدها و رویدادهای کنترل ListView آشنا شده‌اید، یک برنامه‌ی ساده برای نشان دادن توانایی‌های این کنترل ایجاد می‌کنیم. می‌خواهیم یک مرورگر فایل را ایجاد کنیم که به ما اجازه می‌دهد محتوای یک پوشه (Directoy) را مشاهده کنیم. هر زیر پوشه از آن به وسیله‌ی فایل‌ها و فولدرها نمایش داده می‌شوند. یک ویندوز فرم را ایجاد کرده و نام آنرا ListViewDemo قرار دهید. در شکل زیر رابط کاربری را که ما برای فرم خود ایجاد کرده‌ایم را مشاهده می‌کنید.
listview-1002

شماره نوع کنترل نام کنترل خواص
1 ListView listViewFolderFiles View Details
2 TextBox textBoxPath Text C:\
3 Button buttonGo Text Go
4 RadioButton radioButtonLargeIcons Text Large Icons
5 RadioButton radioButtonSmallIcons Text Small Icons
6 RadioButton radioButtonDetails Text Details
Enabled True
7 RadioButton radioButtonList Text List
8 RadioButton radioButtonTile Text Tile

بعد از ساخت رابط کاربری، دو کنترل ImageList نیز بر روی فرم قرار می‌دهیم. یک کنترل ImageList برای نگه داری مجموعه‌ای از تصاویری که توسط کنترل‌های دیگر مثل ListView یا Menu استفاده می‌شوند، بکار می‌رود. تصاویری که در کنترل ImageList نگه داری می‌شوند باید هم اندازه باشند. کنترل ImageList در قسمت Component از جعبه‌ی ابزار (ToolBox) قرار دارد، بنابراین دو عدد از این کنترل را بر روی فرم قرار دهید. به این نکته توجه کنید که این کنترل‌ها به بخش component tray (شکل پایین) اضافه می‌شوند چون جزء کنترل‌های غیر بصری هستند. نام این کنترلها را imageListSmallIcons و imageListLargeIcons قرار دهید.
listview-1003
imageListSmallIcons آیکن های کوچک و imageListLargeIcons تمامی آیکن هایی که باید در کنترل ListView به صورت بزرگ نمایش داده شوند را در خود جای می‌دهد. حال می‌خواهیم تصاویری را به imageListLargeIcon اضافه کنیم. برای اینکار بر روی دکمه‌ای که در سمت راست – بالای این کنترل قرار دارد کلیک کرده و مقدار Image Size را به 32,32 تغییر دهید. اینکار باعث می‌شود که فقط تصاویری به آن اضافه شوند که اندازه‌ی آنها 32,32 باشند.
listview-1004
بر روی دکمه‌ی Choose images کلیک کرده تا پنجره‌ی Image Collection Editor باز شود.
listview-1005
بر روی دکمه‌ی Add کلیک کرده و پوشه‌ی حاوی تصاویر را پیدا کنید. فایل‌های دارای پسوند ico (که مد نظرتان است و قبلاً آماده کرده‌اید) را انتخاب کرده (که ما در این درس دو آیکون با نام‌های Folder_Large.ico و File_Large.ico را انتخاب کرده‌ایم) و بر روی دکمه‌ی Open کلیک کنید. حال فایل‌ها در Image Collection Editor نمایش داده می‌شوند. دکمه‌ی بالا – پایین (Up&Down) در قسمت وسط به شما اجازه می‌دهد که اندیس هر تصویر را تغییر دهید، ما در آینده از آن استفاده خواهیم کرد. مطمئن شوید که Folder_Large.ico دارای اندیس 0 باشد.
listview-1006
بر روی دکمه‌ی OK کلیک کرده تا تصاویر به imageListLargeIcons اضافه شوند. همین کارها را برای imageListSmallIcons نیز انجام دهید. سایز را به 16,16 تغییر داده و فایل‌های Folder_small.ico و Files_Small.ico را پیدا کرده و آنها را انتخاب کنید. همچنین مطمئن شوید که Folder_Small.ico دارای اندیس 0 باشد. آخرین گام برای آماده سازی رابط کاربری، اختصاص دادن کنترلهای Image List که قبلاً ایجاد کرده‌ایم به خواص LargeImageList و SmallImageList کنترل List View است.
در پنجره‌ی خواص (Properties) ، خاصیت LargeImageList را پیدا کرده و بر روی نوار کرکره‌ای کنار آن کلیک کنید و کنترل imageListLargeIcons را انتخاب کنید. همین کار را برای خاصیت SmallImageList انجام داده و کنترل imageListSmallIcons را برای آن انتخاب کنید.
حال برنامه‌ی ما برای کد نویسی آماده است. در حالت طراحی (Design) به وسیله‌ی فشار دادن کلید F7 به پنجره‌ی Code Editor بروید. فضای نام System.IO را اضافه کنید ما از این فضای نام بعداً استفاده می‌کنیم. متدهای زیر را بنویسید، این متدها ستون‌های لازم را به کنترل ListView اضافه می‌کنند.

   1: private void CreateColumns()
   2: {
   3:     ColumnHeader filenameHeader = new ColumnHeader();
   4:     filenameHeader.Text = "Filaname";
   5:     filenameHeader.Width = 150;
   6:     listViewFolderFiles.Columns.Add(filenameHeader);
   7: 
   8:     ColumnHeader lastAccessTimeHeader = new ColumnHeader("Last Accessed");
   9:     lastAccessTimeHeader.Text = "Last Accessed";
  10:     lastAccessTimeHeader.Width = 150;
  11:     listViewFolderFiles.Columns.Add(lastAccessTimeHeader);
  12: 
  13:     ColumnHeader sizeHeader = new ColumnHeader("Size");
  14:     sizeHeader.Text = "Size";
  15:     sizeHeader.Width = 80;
  16:     listViewFolderFiles.Columns.Add(sizeHeader);
  17: }

ما 3 ستون برای کنترل ListView ایجاد کردیم. اولین ستون نام فایلها و نام دایرکتوری را نمایش می‌دهد. دومین ستون، زمان آخرین دسترسی به فایل یا دایرکتوری را نمایش می‌دهد و آخرین ستون حجم هر فایل را نمایش می‌دهد. ما همچنین سایز هر ستون را طوری انتخاب کرده‌ایم که دقیقاً عنوان هر ستون را در خود جای دهد. سپس از متد Add() خاصیت Columns برای اضافه کردن عنوان ستون‌ها استفاده کرده‌ایم. متد زیر را بنویسید، این متد باعث نمایش فایل‌ها و دایرکتوری‌ها در کنترل ListView می‌شود.

   1: private void ShowItemsOfDirectory(string directory)
   2: {
   3:     DirectoryInfo currentDirectory = new DirectoryInfo(directory);
   4:     DirectoryInfo[] subdirectories = currentDirectory.GetDirectories();
   5:     FileInfo[] files = currentDirectory.GetFiles();
   6: 
   7:     listViewFolderFiles.Items.Clear();
   8:     listViewFolderFiles.BeginUpdate();
   9: 
  10:     foreach (DirectoryInfo dir in subdirectories)
  11:     {
  12:         ListViewItem item = new ListViewItem();
  13:         item.Text = dir.Name;
  14:         item.ImageIndex = 0;
  15: 
  16:         ListViewItem.ListViewSubItem subitem = new ListViewItem.ListViewSubItem();
  17:         subitem.Text = dir.LastAccessTime.ToString();
  18:         item.SubItems.Add(subitem);
  19: 
  20:         subitem = new ListViewItem.ListViewSubItem();
  21:         subitem.Text = String.Empty;
  22:         item.SubItems.Add(subitem);
  23: 
  24:         listViewFolderFiles.Items.Add(item);
  25:     }
  26: 
  27:     foreach (FileInfo file in files)
  28:     {
  29:         ListViewItem item = new ListViewItem();
  30:         item.Text = file.Name;
  31:         item.ImageIndex = 1;
  32: 
  33:         ListViewItem.ListViewSubItem subitem = new ListViewItem.ListViewSubItem();
  34:         subitem.Text = file.LastAccessTime.ToString();
  35:         item.SubItems.Add(subitem);
  36: 
  37:         subitem = new ListViewItem.ListViewSubItem();
  38:         subitem.Text = (file.Length / 1000) + " KB";
  39:         item.SubItems.Add(subitem);
  40: 
  41:         listViewFolderFiles.Items.Add(item);
  42:     }
  43: 
  44:     listViewFolderFiles.EndUpdate();
  45: }

این متد یک پارامتر دارد که مسیر دایرکتوریی را که اجزای آن در ListView نمایش داده خواهند شد را نشان می‌دهد. سپس زیر پوشه‌ها و فایل‌ها را با استفاده از متدهای DirectoryInfo.GetDirectories() و DirectoryInfo.GetFiles() استخراج می‌کنیم (خطوط 5-4). در خط 7 با استفاده از متد Clear() تمام آیتم‌های موجود در ListView را پاک می‌کنیم. در خط 8، از متد BeginUpdate() برای اضافه کردن سطر به کنترل استفاده کرده‌ایم. حلقه foreach (خطوط 25-10) برای اضافه کردن زیر پوشه‌های یک پوشه مشخص به کنترل ListView، به کار می‌رود. در خط 12 یک ListViewItem که نشان دهنده یک آیتم یا سطر در ListView است ایجاد شده است. نام پوشه را به خاصیت Text شی item ایجاد شده نسبت می‌دهید. این خاصیت عنوانشی را تعیین می‌کند. خط 14، اندیس تصویر مربوطه را از کنترل ImageList ی که قبلاً به ListView نسبت داده بودیم استخراج می‌کند و به خاصیت ImageIndex نسبت می‌دهد.

به این خاطر که اندیس تصویر پوشه در هر دو ImageList ها برابر 0 است، این مقدار را به خاصیت ImageIndex نسبت داده‌ایم. همچنین FullName را که نشان دهنده مسیر کامل پوشه است به خاصیت Tag، برای استفاده در متد دیگر اضافه می‌کنیم. ستون‌های پست سر هم زیر آیتم‌های هم به حساب می‌آیند. از انجاییکه ما 3 ستون داریم، دو ستون آخر زیرآیتم های ستون اول هستند.

در خط 16 یک شیء ListViewSubItem ایجاد کرده‌ایم. به این نکته توجه کنید که ListViewSubItem کلاس داخلی ListViewItem بوده و شما به آدرس این کلاس (ListViewItem.ListViewSubItem) احتیاج دارید. عنوان ستون دوم را در خط 17 برابر LastAccessTime (آخرین زمان دسترسی) قرار داده‌ایم. برای اضافه کردن زیر آیتم از خاصیت SubItems کلاس ListViewItem استفاده می‌کنیم (خط 18). یک نمونه از کلاس ListViewSubItem در خط 20 برای ستون سوم ایجاد کرده‌ایم. از انجاییکه ما نمی‌خواهیم سایز همه زیر پوشه‌ها را نمایش دهیم از String.Empty برای این کار استفاده کرده‌ایم تا سایز زیر پوشه‌های خالی را نشان ندهد و سپس آن را به خاصیت SubItems از ListViewItem اضافه می‌کنیم.

در خطوط 27-42 یک حلقه foreach دیگر برای شمارش فایل‌های پوشه مورد نظر ما ایجاد شده است. کد این حلقه بسیار شبیه به حلقه اولی است با این تفاوت که از عدد 1 برای ImageIndex استفاده کرده‌ایم. خط 38 سایز فایل بر حسب کیلوبایت را در ستون سوم نمایش می‌دهد. بعد از اینکه همه فایل‌ها اضافه شدند متد EndUpdate() را برای نمایش تغییرات و اضافه کردن سطرها فراخوانی می‌کنیم. سازنده Form1() را با اضافه کردن دو خط کد که همان فراخوانی متدهای CreateColumns() و ShowItemsOfDirectory() می‌باشد، ویرایش می‌کنیم.

   1: public Form1()
   2: {
   3:     InitializeComponent();
   4: 
   5:     CreateColumns();
   6:     ShowItemsOfDirectory(textBoxPath.Text);
   7: }

در خط 6 با فراخوانی متد CreateColumns() سه ستون برای ListView می‌سازیم. در خط 7 متد ShowItemsOfDirectory() را صدا زده و متن موجود در textBoxPath را که همان C:\ به آن ارسال می‌کنیم. بنابراین وقتی برنامه را اجرا می‌کنی محتویات درایو C نمایش داده می‌شود. به محیط طراحی رفته و بر روی دکمه buttonGo دوبار کلیک کرده و کد زیر را در کنترل کننده رویداد آن می‌نویسیم:

private void buttonGo_Click(object sender, EventArgs e)
{
    ShowItemsOfDirectory(textBoxPath.Text);
}

وقتی که کاربر نام یک درایو را در داخل جعبه متن می‌نویسد و سپس بر روی دکمه Go کلیک می‌کند، محتویات درایو نمایش داده می‌شود. در آخر به یک کنترل کننده رویداد برای دکمه‌های رادیویی نیاز داریم که محتویات ListView را در قالب‌های مختلفی نمایش دهد. بر روی هر کدام از دکمه‌های رادیویی کلیک کرده و حالت‌های مختلف نمایش محتویات ListView را با استفاده از خاصیت View این کنترل به هر یک از آنها اختصاص می‌دهیم (خاصیت View کنترل ListView دارای مقادیری است که محتویات این کنترل را به صورت آیکن بزرگ، آیکن ریز، لیست و … نمایش می‌دهد).

private void radioButtonLargeIcons_CheckedChanged(object sender, EventArgs e)
{
    listViewFolderFiles.View = View.LargeIcon;
}

private void radioButtonSmallIcons_CheckedChanged(object sender, EventArgs e)
{
    listViewFolderFiles.View = View.SmallIcon;
}

private void radioButtonDetails_CheckedChanged(object sender, EventArgs e)
{
    listViewFolderFiles.View = View.Details;
}

private void radioButtonList_CheckedChanged(object sender, EventArgs e)
{
    listViewFolderFiles.View = View.List;
}

private void radioButtonTile_CheckedChanged(object sender, EventArgs e)
{
    listViewFolderFiles.View = View.Tile;
}

برنامه را اجرا و نحوه نمایش محتویات درایو C:\ را مشاهده کنید. نام درایو دیگر را در داخل جعبه متن نوشته و بر روی دکمه Go کلیک کنید تا محتویات آن نمایش داده شوند. حال به صورت زیر نحوه نمایش محتویات درایوها در ListView را با کلیک بر روی هر دکمه رادیویی تغیییر دهید.
listview-1007
listview-1008