فى هذه الجزئية سنتحدث عن السحب والإفلات
In computer graphical user interfaces, drag-and-drop is the action of (or support for the action of) clicking on a virtual object and dragging it to a different location or onto another virtual object. In general, it can be used to invoke many kinds of actions, or create various types of associations between two abstract objects. (Wikipedia)
السحب والإفلات احد اوضح جوانب الواجهات الرسومية. عمليات السحب والإفلات تتيح عمل اشياء معقدة
عادة نستطيع ان نسحب ونفلت نوعين بيانات او بعض الأوبجكتس الرسومية. اذا سحبنا صورة من تطبيق لآخر فإننا نقوم بسحب وإفلات بيانات binary اذا قمنا بسحب نافذة فى متصفح فايرفوكس من مكان لآخر فإننا نقوم بسحب مكون رسومى
فى المثال، سنقوم بعملية السحب والإفلات على زر خارج بروتوكول السحب والإفلات
dragbutton.cs using System; using System.Drawing; using System.Windows.Forms; public class MForm : Form { private bool isDragging = false; private int oldX, oldY; private Button button; public MForm() { Text = "Drag & drop button"; Size = new Size(270, 180); button = new Button(); button.Parent = this; button.Cursor = Cursors.Hand; button.Text = "Button"; button.Location = new Point(20, 20); button.MouseDown += new MouseEventHandler(OnMouseDown); button.MouseUp += new MouseEventHandler(OnMouseUp); button.MouseMove += new MouseEventHandler(OnMouseMove); CenterToScreen(); } public static void Main() { Application.Run(new MForm()); } private void OnMouseDown(object sender, MouseEventArgs e) { isDragging = true; oldX = e.X; oldY = e.Y; } private void OnMouseMove(object sender, MouseEventArgs e) { if (isDragging) { button.Top = button.Top + (e.Y - oldY); button.Left = button.Left + (e.X - oldX); } } private void OnMouseUp(object sender, MouseEventArgs e) { isDragging = false; } }
نضع زر فى نافذة، وبالضغط على الزر وسحبه بالفأرة نستطيع ان نعيد تحديد موقع الزر
private bool isDragging = false; private int oldX, oldY;
متغيرات مساعدة فى مثالنا ، isDragging ليعبر عما اذا كانت عملية سحب للكائن ام لا و oldX, oldY متغيرات لتخزين الإحداثيات القديمة قبل بدء عملية السحب
button.MouseDown += new MouseEventHandler(OnMouseDown); button.MouseUp += new MouseEventHandler(OnMouseUp); button.MouseMove += new MouseEventHandler(OnMouseMove);
نربط 3 احداث خاصة بالمؤشر توثر على الزر (3 مراحل لعملية السحب والإفلات) بمعالجات مناسبة
private void OnMouseDown(object sender, MouseEventArgs e) { isDragging = true; oldX = e.X; oldY = e.Y; }
الطريقة OnMouseDown هى اول جزء فى العملية حيث نحدد المتغيرات ال 3 المطلوبة
private void OnMouseMove(object sender, MouseEventArgs e) { if (isDragging) { button.Top = button.Top + (e.Y - oldY); button.Left = button.Left + (e.X - oldX); } }
الطريقة OnMouseMove تعيد تحديد موضع الزر ثم نحسب الفرق بين الإحداثيات الجديدة والقديمة ونقوم بإضافة ذلك الفرق لأعلى ويسار (Top, Left) الخاصة بالزر وننقله للمكان الجديد
Figure: Dragging a button
فى المثال السابق سحبنا وافلتنا اداة، الآن سنطبق العملية على بيانات نصية، وسنستخدم بروتوكول السحب والإفلات المقدم من WinForms
للسحب والإفلات بروتوكول قياسى ، لدينا كائنين (مصدر السحب والهدف)
dragtext.cs using System; using System.Drawing; using System.Windows.Forms; public class MForm : Form { private TextBox textBox; private Button button; public MForm() { InitForm(); CenterToScreen(); } private void OnMouseDown(object sender, MouseEventArgs e) { TextBox txt = (TextBox) sender; txt.DoDragDrop(txt.Text, DragDropEffects.Copy); } private void OnDragEnter(object sender, DragEventArgs e) { e.Effect = DragDropEffects.Copy; } private void OnDragDrop(object sender, DragEventArgs e) { Button button = (Button) sender; button.Text = (string) e.Data.GetData(DataFormats.Text); } private void InitForm() { Text = "Drag & drop"; button = new Button(); textBox = new TextBox(); SuspendLayout(); button.AllowDrop = true; button.Location = new Point(150, 50); textBox.Location = new Point(15, 50); button.DragDrop += new DragEventHandler(OnDragDrop); button.DragEnter += new DragEventHandler(OnDragEnter); textBox.MouseDown += new MouseEventHandler(OnMouseDown); ClientSize = new Size(250, 200); Controls.Add(button); Controls.Add(textBox); ResumeLayout(); } public static void Main(string[] args) { Application.Run(new MForm()); } }
لدينا اداتين على النافذة زر وحقل ادخال، سنسحب النص على حقل الإدخال ونفلته على الزر.
InitForm();انشاء النافذة تم تحويله للطريقة InitForm “يستخدم غالبا فى التطبيقات الكبيرة"
Setting up of the form is delegated to the InitForm() method. This is usually done in larger applications.
SuspendLayout(); ... ResumeLayout();
نضع الأداتين بين هاتين الطريقتين "للتحسين" لإيقاف الإجفال
button.AllowDrop = true;نحدد AllowDrop للسماح بإمكانية الإفلات على الزر
button.DragDrop += new DragEventHandler(OnDragDrop); button.DragEnter += new DragEventHandler(OnDragEnter); textBox.MouseDown += new MouseEventHandler(OnMouseDown);
مرة اخرى، تنقسم عملية السحب والإفلات ل 3 خطوات. لدينا 3 طرق لمعالجة كل خطوة
private void OnMouseDown(object sender, MouseEventArgs e) { TextBox txt = (TextBox) sender; txt.DoDragDrop(txt.Text, DragDropEffects.Copy); }
فى الطريقة OnMouseDown نجهز عملية السحب والإفلات، نبدأ العملية بالطريقة DoDragDrop ، وبإستخدام المعامل DragDropEffects.Copy ستقوم بنسخ مايتم سحبه (تستطيع تحديد ماذا كان يتم نقله تماما)
private void OnDragEnter(object sender, DragEventArgs e) { e.Effect = DragDropEffects.Copy; }
يتم اطلاق DragEnter عن دخول مؤشر الفأرة الى منطقة الهدف، يجب تحديد خاصية التأثير Effect،
private void OnDragDrop(object sender, DragEventArgs e) { Button button = (Button) sender; button.Text = (string) e.Data.GetData(DataFormats.Text); }
اخيرا لدينا OnDragDrop ، هنا نحصل على البيانات من متغير معاملات الحدث ونسندها ل button.Text
Figure: Drag & drop of text
فى المثال الأخير سنسحب ونفلت صورة.
dragimage.cs using System; using System.Drawing; using System.Windows.Forms; public class ImageDragDrop : Form { private bool isDragging; private int oldX, oldY; private Rectangle dropRect; private PictureBox picBox; private Bitmap image; private Brush brush; public ImageDragDrop() { ClientSize = new Size(350, 250); Text = "Dragging Image"; Paint += new PaintEventHandler(OnPaint); isDragging = false; dropRect = new Rectangle(10, 10, 200, 160); brush = Brushes.Gray; picBox = new PictureBox(); loadImage(); picBox.Parent = this; picBox.Location = new Point(100, 50); picBox.Size = new Size(image.Width, image.Height); picBox.Image = image; picBox.Cursor = Cursors.Hand; picBox.MouseDown += new MouseEventHandler(OnMouseDown); picBox.MouseUp += new MouseEventHandler(OnMouseUp); picBox.MouseMove += new MouseEventHandler(OnMouseMove); CenterToScreen(); } void loadImage() { try { image = new Bitmap("image.jpg"); } catch { Console.WriteLine("Error reading image"); Environment.Exit(1); } } public static void Main() { Application.Run(new ImageDragDrop()); } private void OnMouseDown(object sender, MouseEventArgs e) { isDragging = true; oldX = e.X; oldY = e.Y; } private void OnMouseMove(object sender, MouseEventArgs e) { if (isDragging) { picBox.Top = picBox.Top + (e.Y - oldY); picBox.Left = picBox.Left + (e.X - oldX); } } private void OnMouseUp(object sender, MouseEventArgs e) { isDragging = false; if(dropRect.Contains(picBox.Bounds)) { brush = Brushes.Gold; } else { brush = Brushes.Gray; } Refresh(); } private void OnPaint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; g.FillRectangle(brush, dropRect); } }
فى مثالنا لدينا PictureBox ورسمنا مستطيل رمادى، اذا سحبنا الصورة داخل المستطيل يتغير لونه الى الذهبى
brush = Brushes.Gray;متغير الفرشاة يحوى فرشاة المستطيل (رمادية افتراضيا)
void loadImage() { try { image = new Bitmap("image.jpg"); } catch { Console.WriteLine("Error reading image"); Environment.Exit(1); } }
الطريقة loadImage تقوم بتحميل bitmap الى اداة ال PictureBox
The loadImage() loads a bitmap for the PictureBox control.
if (dropRect.Contains(picBox.Bounds)) { brush = Brushes.Gold; } else { brush = Brushes.Gray; }
فى الطريقة OnMouseUp .. نحدد فرشاة المستطيل، اذا ماكانت حدود الPictureBox داخل المستطيل، فتكون الفرشاة ذهبية والا تكون رمادية
Refresh();نستدعى الطريقة Refresh لتفعيل لون الفرشاة الجديد
Figure: Drag & drop image
كان هذا الفصل مخصصا للسحب والإفلات بإستخدام WinForms
Home Contents Top of Page