ایجاد منوی pop up و عمل دراگ کردن
شاید تو بعضی برنامه ها لازم باشه برای راحتی کار، منویی بذاریم که با راست کلیک کردن ظاهر بشه و هر قسمتش کار خاصی رو انجام بده یا تابع خاصی رو فراخوانی بکنه.
برای اینکار، می تونیم از ابزاری به نام ContextMenu به صورت زیر استفاده کنیم.
این ابزار مثل همون منوی عادیه منتها در بالای فرم نشان داده نمی شه. با کلیک کردن روی قسمت های مختلف اون می توانیم زیر منوهامون رو درست بکنیم و نام گذاری کنیم.
حالا فرض کنید که دو زیر منو به نامهای Copy , Move ایجاد کردیم. و فرض کنید که دو تا TextBox به نامهای Text1,Text2 داریم.و همچنین یک RichTextBox به نام RText1 داریم. روال کار اینجوریه که، در Text1,Text2 متنی می نویسیم و آن رو به داخل RText1 دراگ(Drog and Drop) می کنیم. با این تفاوت که بعد دراگ کردن متن داخل Text1 کات(Cut) میشه ولی متن داخل Text2 کپی میشه و اگر عمل دراگ رو با دکمه سمت راست موس(راست کلیک) انجام دادیم، داخل Rtext1 به جای کپی یا کات کردن منویی ظاهر بشه و از کاربر بپرسه که کپی کنه یا کات کنه.
کد مربوط به Text1 :
private void Text1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
sourceControl = textBox1;
mouseButton = e.Button;
textBox1.DoDragDrop(textBox1.Text, DragDropEffects.Move | DragDropEffects.Copy);
}
sourceControl: به کمک این می تونیم شی مبدا رو مشخص کنیم. (مثلا می خواهیم کپی کنیم، پس باید دونیم از کجا به کجا کپی صورت بگیره. به کمک این دستور شی مبدا رو کنترل می کنیم.)
mouseButton: به کمک این دستور کیلد موس که فشار داده شده و مشخص می کنیم. (این دستور رو داخل رویداد MouseDown نوشته ایم.)
DoDragDrop(): به کمک این متد مشخص می کنیم که عمل کشیدن چه تغییری در شی مشخص شده اعمال بکند(کپی کند یا کات کند)، که اینجا گفتیم که هم کپی کند هم کات کند. یعنی بعد از کپی کردن متن، مقدارش پاک بشه.
متن مربوط به Text2:
private void Text2_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
sourceControl = textBox1;
mouseButton = e.Button;
textBox1.DoDragDrop(textBox1.Text, DragDropEffects.Copy);
}
این هم شبیه Text1 است با این تفاوت که اینجا متن فقط کپی میشه.
کد مربوط به RText1:
private void RText1_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
sourceData = e.Data.GetData(DataFormats.Text, true).ToString();
if (mouseButton == MouseButtons.Right)
{
mnuCopy.Visible = ((e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy);
mnuMove.Visible = ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move);
contextMenu1.Show(RText1, new Point(20,20));
}
else
{
deleteSource = (e.Effect == DragDropEffects.Move);
ProcessData();
}
}
sourceData: مقداری که کپی یا کات شده در آن قرار می گیره.
اگر با کلیک راست دراگ کرده باشیم، زیر منوهای کپی و کات از منوی ContextMenu ظاهر میشن و نشان داده میشن. البته در مختصاتی که بهش می دیم.(اینجا گفتیم در نقطه 20 و 20 از شی RText1 منو ظاهر بشه.)و اگر راست کلیک نباشه، و جاهایی که کات کردیم(در Text1) مقدار True رو برامون بر گردونه.
تابع ProcessData() به صورت زیره:
private void ProcessData()
{
RText1.Text = sourceData;
if (deleteSource)
{
Text1.clear();
}
sourceControl = null;
mouseButton = MouseButtons.None;
deleteSource = false;
}
اینجا مقداری رو که درگ کردیم رو داخل RText1 کپی کنه. اگه مقدار deleteSource درست باشه(True) مقدار Text1 رو پاک بکنه. و آخر سر متغیرهای کمکی که استفاده کردیم، مقدارشون رو پاک کنه.
حالا فقط مونده توابعی که برای کپی یا کات استفاده کردیم.
private void Copy_Click(object sender, System.EventArgs e)
{
deleteSource = false;
ProcessData();
}
private void Move_Click(object sender, System.EventArgs e)
{
deleteSource = true;
ProcessData();
}
این توابع هم فقط deleteSource رو مقدار دهی می کنن. اگه True باشه یعنی کپی، اگه False باشه یعنی کات.
