User Control

ویژوال استودیو این توانایی را به شما می‌دهد که یک کنترل به دلخواه خود، علاوه بر کنترل‌های از پیش تعریف شده در آن، ایجاد کنید. ممکن است که شما دوست داشته باشید یک کنترل با ویژگی‌های خاص داشته باشید و همچنین کنترلی در میان کنترل‌های معمول ویژوال استودیو وجود نداشته باشد. این کنترل‌های سفارشی می‌توانند همراه با دیگر کنترل‌ها در قسمت نوار ابزار قرار گیرند.

دو نوع کنترل وجود دارد که توسط کاربر تعریف می‌شوند : user control و کنترل‌های سفارشی. user control ترکیبی از کنترل‌های از قبل تعریف شده بوده و ساخت آنها بسیار آسان است. کنترل‌های سفارشی از قبل وجود نداشته و برای ایجاد آنها باید کدنویسی کرد. تمرکز اصلی ما در این درس بر روی User Controls است. چون ایجاد کنترل‌های سفارشی مستلزم آشنایی با مفاهیم پیشرفته برنامه نویسی بوده و برای آموزش کسانی که در سطح مبتدی هستند مناسب نیست.

User controls از کلاس UserControl ارث بری می‌کند، که این کلاس نیز، مشتق کلاس Control است، که کنترل‌ها از آن استفاده می‌کنند. همه متدها و خاصیت‌های اجزای بصری یا کنترل‌هایی که در User control به کار رفته‌اند در دسترس شما نیستند چون فقط متدها و خواص کلاس UserControl به شما ارائه می‌شود. ولی می‌توان متدها یا خاصیت‌هایی تعریف کرد که با کنترل‌های User control در ارتباط باشند.

حال یک کنترل به نام EditableLabel ایجاد می‌کنیم. کنترلی که ایجاد می‌کنیم شبیه به یک کنترل lable است و وقتی که کاربر بر روی آن دو بار کلیک می‌کند به شکل یک کنترل textbox درمی آید که متن lable را در خود دارد. شما می‌توانید متن textbox را ویرایش کنید و وقتی دکمه enter را فشار دهید textbox دوباره تبدیل به یک lable ولی با متن ویرایش شده شود.

برنامه ویژوال استودیو را باز کرده و یک پروژه جدید را ایجاد کنید. از لیست templates گزینه Windows Forms Control Library را انتخاب کرده و نام آن را EditableLabel بگذارید:


شکل زیر ظاهر می‌شود :

همانطور که می‌بینید شکل بالا شبیه به یک پنجره ویندوزی بدون قاب است. هر کنترلی که به این پنجره یا user control اضافه شود جزئی از آن می‌شود. بر روی کادر کلیک کرده و خاصیت Name آن را به EditableLabel و خاصیت AutoSize را به True تغییر دهید:

یک کنترل label را بر روی کادر بکشید و خاصیت Text آن را به Label و خاصیت Name آن را به labelDisplay تغییر دهید. اندازه کادر را طوری تغییر دهید که برابر اندازه label شود :

اضافه کردن خاصیت‌ها

از آنجاییکه ما یک user control ایجاد کرده‌ایم در نتیجه فقط رویدادها یا خاصیت‌های کلاس UserControl در دسترس ما قرار دارد. این بدان معناست که ما نمی‌توانیم به خاصیت‌های کنترل Lable ی که به فرم اضافه کرده‌ایم، دسترسی داشته باشیم. با وجودیکه کلاس UserControl دارای خاصیت Text است که از کلاس Control به ارث برده اما ما نیاز به توابع بیشتری برای کار با کنترل Lable مان داریم. برای اضافه کردن یک خاصیت به user control، نیاز به اضافه کردن خاصیت به کلاس user control مان داریم. اگر در محیط طراحی هستید با زدن دکمه F7 به قسمت کدنویسی بروید و در داخل کلاس EditableLabel خاصیت زیر را اضافه کنید :

[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text
{
	get { return labelDisplay.Text; }
	set { labelDisplay.Text = value; }
}

به دو صفت بالای خاصیت توجه کنید. صفت Browsable به خاصیت اجازه می‌دهد که در پنجره Properties محیط Visual Studio نمایش داده شود. اگر این صفت را اضافه نکنید و مقدار آن را برابر true قرار ندهید، فقط در محیط کدنویسی به خاصیت دسترسی خواهید داشت نه در محیط طراحی. دومین صفت (DesignerSerializationVisibility) به ما اجازه تغییر خاصیت‌های user control در پنجره Property را می‌دهد. به این نکته نیز توجه کنید که ما از کلمه کلیدی override به این دلیل که خاصیت Text در User Control نیز وجود دارد استفاده می‌کنیم .

اضافه کردن کنترل کننده رویداد (Event Handlers)

حال وقت آن رسیده که به user control، کنترل کننده رویداد اضافه کنیم. قبلاً گفتیم که با دوبار کلیک بر روی کنترل EditableLabel مان شکل آن به textbox تغییر می‌کند. بنابراین لازم است که یک کنترل کننده رویداد به رویداد DoubleClick آن اضافه شود. کنترل Lable را انتخاب می‌کنیم. سپس از پنجره Properties به سربرگ رویدادها رفته و رویداد DoubleClick را انتخاب و بر روی آن دو بار کلیک می‌کنیم. با این کار یک کنترل کننده رویداد برای رویداد DoubleClick ایجاد می‌شود.

حال لازم است که یک کنترل TextBox را هم به user control اضافه کنیم. فیلد زیر را در داخل کلاس EditableLabel اضافه می‌کنیم:

private TextBox editableTextBox;

حال در داخل سازنده کلاس EditableLabel و بعد از متد InitializeComponent کد زیر را اضافه کنید :

public EditableLabel()
{
    InitializeComponent();

    editableTextBox = new TextBox();   
    this.Controls.Add(editableTextBox);
    editableTextBox.Hide();                                                                   

}

با کد بالا کنترل TextBox به مجموعه کنترل‌های user control اضافه می‌شود. از آنجاییکه ما می‌خواهیم ابتدا کنترل Lable نمایش داده شود نه textbox، با استفاده از متد Hide کنترل textbox را مخفی می‌کنیم. حال به اجازه بدهید که به کنترل کننده رویداد کنترل Lable بر گردیم.

private void labelDisplay_DoubleClick(object sender, EventArgs e)
{
    editableTextBox.Size = this.Size;
    editableTextBox.Text = labelDisplay.Text;
    labelDisplay.Hide();
    editableTextBox.Show();
    editableTextBox.Focus();
}

کد بالا کنترل کننده رویداد مربوط به رویداد DoubleClick کنترل lable می‌باشد. همانطور که می‌بینید اندازه textbox را برابر با اندازه user control قرار داده‌ایم. سپس متن آن را با متن lable برابر قرار می‌دهیم. در مرحله بعد با استفاده از متد Hide کنترل lable را مخفی می‌کنیم. و در نهایت فوکوس را بر روی textbox قرار می‌دهیم تا کاربر بتواند آن را ویرایش کند. حال نیاز به یک کنترل کننده رویداد داریم که به کاربر اجازه می‌دهد تغییرات متن textbox را در خاصیت text کنترل lable ذخیره کند. در داخل سازنده کلاس EditableLabel و بعد از متد ()InitializeComponent، کد زیر را وارد کنید :

editableTextBox = new TextBox();
this.Controls.Add(editableTextBox);
editableTextBox.KeyDown += new KeyEventHandler(editableTextBox_KeyDown);
editableTextBox.Hide();

یک کنترل کننده رویداد را به رویداد KeyDown اضافه می‌کنیم. وقتی که کاربر متن textbox را ویرایش کرد می‌تواند دکمه Enter را فشار دهد. کنترل کننده رویداد مربوط به رویداد KeyDown را به صورت زیر تعریف می‌کنیم :

void editableTextBox_KeyDown(object sender, KeyEventArgs e)
{
   if (e.KeyCode == Keys.Enter)
   {
       labelDisplay.Text = editableTextBox.Text;
       editableTextBox.Hide();
       labelDisplay.Show();
   }
}

در کد بالا ابتدا چک می‌کنیم که آیا دکمه Enter توسط کاربر زده شده یا نه؟ سپس متن جاری lable مخفی را برابر متن جدیدی که توسط کاربر نوشته شده است قرار می‌دهیم. در مرحله بعد textbox را مخفی و کنترل lable با متن جدید را نمایش می‌دهیم. و در آخر وقتی که کنترل lable بسته به طول متن تغییر اندازه داد، user control نیز تغییر اندازه می‌دهد. بر روی labelDisplay در محیط طراحی کلیک کرده و در پنجره Properties از بخش Event ها رویداد Resize را پیدا کرده و بر روی آن دو بار کلیک و سپس کد زیر را در کنترل کننده رویداد وارد می‌کنیم :

private void labelDisplay_Resize(object sender, EventArgs e)
{
    this.Size = labelDisplay.Size;
}

کنترل کننده رویداد به سادگی اندازه user control را برابر اندازه جدید labelDisplay می‌کند.

کامپایل User Control

حال نوبت به کامپایل کنترل می‌رسد. برای این کار به قسمت menu رفته و سپس بر روی گزینه Build و بعد از آن Build Solution کلیک می‌کنید:

با انجام این عمل یک فایل با پسوند dll. ساخته می‌شود که شامل user control شما می‌باشد.

امتحان کردن کنترل

برای تست کنترل جدید لازم است که یک پروژه جدید ایجاد کنیم. برنامه ویژوال استودیو را بسته و یک پروژه جدید ویندوزی (Windows Forms Application) ایجاد کنید و نام آن را به EditableLabelDemo تغییر دهید. وقتی که پنجره ویندوزی جدید ظاهر شد بر روی ToolBox راست کلیک کرده و مانند شکل زیر گزینه “…Choose Items” را انتخاب نمایید :

در پنجره ظاهر شده که عنوان آن Choose Toolbox Items می‌باشد بر روی دکمه Browse کلیک کنید:

سپس به دنبال فایل dll ی که شامل user control است بگردید. این فایل در پوشه‌ای که پروژه‌تان در آن ذخیره شده است قرار دارد. در داخل پوشه پروژه‌مان که نام آن EditorLabel یک پوشه به نام bin وجود دارد، وارد آن (پوشه bin) می‌شویم. در درون پوشه ممکن است پوشه یا پوشه‌های به نام‌های Debug یا Release وجود داشته باشد که فایل dll در درون آنها باشد. وقتی که فایل EditorLabel.dll را پیدا کردید آن را انتخاب و بر روی گزینه open کلیک کنید:


حال مشاهده می‌کنید که کنترل EditorLabel در درون کنترل‌های قابل انتخاب واقع در Toolbox به نمایش در خواهد آمد.

EditableLabel را بر روی فرم بکشید. با کشیدن کنترل بر روی فرم مشاهده می‌کنید که خاصیت Text این کنترل به خاطر اضافه شدن صفت Browsable، در پنجره Properties قابل مشاهده است:

پروژه را اجرا کرده و بر روی label دو بار کلیک کنید. متن را تغییر داده و دکمه Enter را بزنید.





همانطور که مشاهده می‌کنید متن lable به متنی که شما در textbox وارد کرده‌اید تغییر می‌کند. همه کد مربوط به این درس به صورت زیر است:

 1: using System;
 2: using System.ComponentModel;
 3: using System.Windows.Forms;
 4: 
 5: namespace EditableLabel
 6: {
 7:     public partial class EditableLabel: UserControl
 8:     {
 9:         [Browsable(true)]
10:         [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
11: 
12:         public override string Text
13:         {
14:             get { return labelDisplay.Text; }
15:             set { labelDisplay.Text = value; }
16:         }
17: 
18:         private TextBox editableTextBox;
19: 
20:         public EditableLabel()
21:         {
22:             InitializeComponent();
23: 
24:             editableTextBox = new TextBox();
25:             this.Controls.Add(editableTextBox);  
26:             editableTextBox.KeyDown += new KeyEventHandler(editableTextBox_KeyDown);          
27:             editableTextBox.Hide();
28:         }
29: 
30:         void editableTextBox_KeyDown(object sender, KeyEventArgs e)
31:         {
32:             if (e.KeyCode == Keys.Enter)
33:             {
34:                 labelDisplay.Text = editableTextBox.Text;
35:                 editableTextBox.Hide();
36:                 labelDisplay.Show();
37:             }
38:         }
39: 
40:         private void LabelDisplay_DoubleClick(object sender, EventArgs e)
41:         {
42:             editableTextBox.Size = this.Size;
43:             editableTextBox.Text = labelDisplay.Text;
44:             labelDisplay.Hide();
45:             editableTextBox.Show();
46:             editableTextBox.Focus();
47:         }
48: 
49:         private void LabelDisplay_Resize(object sender, EventArgs e)
50:         {
51:             this.Size = labelDisplay.Size;
52:         }
53:     }
54: }