Drag and drop using a class method

坚强是说给别人听的谎言 提交于 2019-12-13 02:09:38

问题


I have a range of drag drop activities all working fine on my quiz. (From answering questions to selecting an avatar)

There is a lot of repetition of the code and I am thinking it would be better implemented from a class and call the method each time that I use a drag drop.

Firstly can this be done? and secondly would I need a new method for the dragging and dropping?

Any thoughts or rough ideas would be great.

private void pictureBox2_MouseDown(object sender, MouseEventArgs e)
{
pictureBox2.DoDragDrop(pictureBox2.Image, DragDropEffects.Copy);
}

private void panel1_DragEnter(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.Copy;
}

private void panel1_DragDrop(object sender, DragEventArgs e)
{
    //Set background image of panel to selected avatar'
    panel1.BackgroundImage = (Image)e.Data.GetData(DataFormats.Bitmap);
}

回答1:


If all you want is to avoid duplicating the same events of several controls you should use common events:

private void commonPBox_MouseDown(object sender, MouseEventArgs e)
{
    PictureBox PB = sender as PictureBox;
    if (PB == null) return; //or throw an exception

    PB.DoDragDrop(PB.Image, DragDropEffects.Copy);
}

private void commonPanel_DragEnter(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.Copy;
}

private void commonPanel_DragDrop(object sender, DragEventArgs e)
{
    Panel Pan = sender as Panel;
    if (Pan == null) return; //or throw an exception

    //Set background image of panel to selected avatar
    Pan.BackgroundImage = (Image)e.Data.GetData(DataFormats.Bitmap);
}

Select the respective controls and enter the event names into the respective event name slots in the event pane of the properties tab.

Note how I cast the sender param of the event to get a types reference to the control that triggers the event. If the cast goes wrong the reference is set to null.

If you want more control and more flexibilty you may consider creating a DragAndDropcontroller class..:

static class DnDCtl
{
    static List<Control> Targets = new List<Control>();
    static List<Control> Sources = new List<Control>();

    static public void RegisterSource(Control ctl)
    {
        if (!Sources.Contains(ctl) ) 
        {
            Sources.Add(ctl);
            ctl.MouseDown += ctl_MouseDown;
        }
    }

    static public void UnregisterSource(Control ctl)
    {
        if (Sources.Contains(ctl))
        {
            Sources.Remove(ctl);
        }
    }

    static public void RegisterTarget(Control ctl)
    {
        if (!Targets.Contains(ctl))
        {
            Targets.Add(ctl);
            ctl.DragEnter += ctl_DragEnter;
            ctl.DragDrop += ctl_DragDrop;
            ctl.AllowDrop = true;
        }
    }

    static public void UnregisterTarget(Control ctl)
    {
        if (Targets.Contains(ctl))
        {
            Targets.Remove(ctl);
            ctl.DragEnter -= ctl_DragEnter;
            ctl.DragDrop -= ctl_DragDrop;

        }
    }

    static void ctl_MouseDown(object sender, MouseEventArgs e)
    {
        PictureBox PB = sender as PictureBox;
        if (PB != null) PB.DoDragDrop(PB.Image, DragDropEffects.Copy);

        Panel Pan = sender as Panel;
        if (Pan != null) Pan.DoDragDrop(Pan.BackgroundImage, DragDropEffects.Copy);
    }

    static void ctl_DragEnter(object sender, DragEventArgs e)
    {
        e.Effect = DragDropEffects.Copy;
    }

    static void ctl_DragDrop(object sender, DragEventArgs e)
    {
        Panel Pan = sender as Panel;
        if (Pan != null) Pan.BackgroundImage = (Image)e.Data.GetData(DataFormats.Bitmap);

        PictureBox PB = sender as PictureBox;
        if (PB != null) PB.BackgroundImage = (Image)e.Data.GetData(DataFormats.Bitmap);
    }
}

Notes:

  • I have coded symmetric actions for Panels and PictureBoxes to show how you can handle different controls.
  • I have created but not used Lists of sources and targets. For more complex projects you will find them useful.
  • I have coded both Register and Unregister methods. You can register after some condition and unregister when it no longer applies
  • Such a Controller is good for dynamically alowing or disallowing Drag&Drop for controls, esp. when you create them dynamically.
  • You could also pass around delegates to decouple the dragdrop action from the controller.

Also note that some folks sometimes do prefer to use the MouseMove event over MouseDown esp. as it won't so easily interfere with making a selection.

ListView has a dedicated event instead, ListView.ItemDrag, which obviously should be used when registering!



来源:https://stackoverflow.com/questions/33284997/drag-and-drop-using-a-class-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!