使用类方法拖放

时间:2015-10-22 15:37:55

标签: c# .net winforms drag-and-drop

我的一系列拖放活动在我的测验中都运行良好。 (从回答问题到选择头像)

代码有很多重复,我认为从类中实现更好,每次使用拖放时调用方法。

首先可以这样做吗?第二,我需要一种新的拖放方法吗?

任何想法或粗略的想法都会很棒。

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 个答案:

答案 0 :(得分:2)

如果您只想避免重复多个控件的相同事件,则应使用常见事件:

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);
}

选择相应的控件,并在属性选项卡的事件窗格中的相应事件名称插槽中输入事件名称。

请注意我如何转换事件的sender参数以获取触发事件的控件的类型引用。如果演员出错,则引用设置为null

如果您想要更多控制和更多灵活性,您可以考虑创建一个DragAndDropcontroller类..:

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);
    }
}

注意:

  • 我为PanelsPictureBoxes编写了对称操作,以说明如何处理不同的控件。
  • 我创建但未使用Lists来源和目标。对于更复杂的项目,您会发现它们很有用。
  • 我已经编码了RegisterUnregister两种方法。您可以在某些条件后注册,并在不再适用时取消注册
  • 这样的控制器适用于动态控制或禁止拖放控制,尤其是控制。当你动态创建它们时。
  • 您还可以传递代理以将拖放操作与控制器分离。

另请注意,有些人有时更喜欢使用MouseMove事件而不是MouseDown esp。因为它不会轻易干扰选择。

ListView有一个专门的活动,ListView.ItemDrag,显然应该在注册时使用!