Winform DragDrop事件效率

时间:2014-01-10 20:15:43

标签: c# winforms drag-and-drop event-handling

我儿子和我正在为Farkle的骰子游戏一起制作一个爱好项目(Winform应用程序),需要有关处理骰子拖拽事件的指导。请注意我们不是在寻找答案或代码;关于解决方案攻击的一些一般想法。

以下是构造:

RolledDice - 我们有一个带有两个面板的单一表格。一个面板包含6个PictureBoxes,它基于我们构建的DiceRoller类显示来自ImageList的骰子图像,以生成从1到6的随机整数。我们使用支持PictureBox数组迭代每个PictureBox。 “掷骰子”按钮的点击事件显示滚动的骰子 - 一切都很好,这很好用。

PlayerDice - 第二个面板的配置与第一个面板相同,并接受从“滚动骰子”面板拖动的用户选择的骰子。我们的用例需要用户能够将骰子从“滚动骰子”面板拖动到“玩家骰子”面板,如果用户改变他们想要保留骰子的想法,则需要再次返回 - 一切都很好,这很有用。

问题陈述 - 虽然我们可以将骰子从“滚动骰子”面板拖动到“播放器骰子”面板(并在此过程中更新后备PictureBox数组),但是对于两个面板中的6个PictureBox中的每一个,都需要有三个事件处理程序(MouseDown,DragEnter和DragDrop),这相当于一大堆代码。

问题 - 有一个优雅的方法可以为所有滚动骰子提供一组这3个事件处理程序,并为所有玩家骰子提供一组这些事件处理程序,而不是像我们现在拥有的一堆字符串代码?

同样,我们不是在寻找确切的答案或代码,只是关于解决方案攻击的一些一般性想法。

EDITED: 以下是我们为ONE图像提供的代码。

    #region Mouse and Drag Events
    // Mouse and Drag Events for ONE Rolled Dice
    void pbRolled1_MouseDown(object sender, MouseEventArgs e)
    {
        PictureBox source = (PictureBox)sender;
        DoDragDrop(source.Image, DragDropEffects.Move);
    }
    void pbRolled1_DragEnter(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(DataFormats.Bitmap))
            e.Effect = DragDropEffects.Move;
    }
    void pbRolled1_DragDrop(object sender, DragEventArgs e)
    {
        PictureBox destination = (PictureBox)sender;
        destination.Image = (Bitmap)e.Data.GetData(DataFormats.Bitmap);
    }

    // Mouse and Drag Events for ONE Player Dice
    void pbPlayer1_MouseDown(object sender, MouseEventArgs e)
    {
        PictureBox source = (PictureBox)sender;
        DoDragDrop(source.Image, DragDropEffects.Move);
    }
    void pbPlayer1_DragEnter(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(DataFormats.Bitmap))
            e.Effect = DragDropEffects.Move;
    }
    void pbPlayer1_DragDrop(object sender, DragEventArgs e)
    {
        PictureBox destination = (PictureBox)sender;
        destination.Image = (Bitmap)e.Data.GetData(DataFormats.Bitmap);
    }
    #endregion

2 个答案:

答案 0 :(得分:1)

您不一定需要在控件及其事件之间建立一对一的关系 - 事件可以在控件之间共享。

由于您不想要特定的答案,我会给您一个一般的例子。采用这个简单的形式,有三个按钮和一个标签:

Simple Windows Form

现在,这个简单表单的代码如下(Form1.cs):

   public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            this.button1.Click += new System.EventHandler(this.button_Click);
            this.button2.Click += new System.EventHandler(this.button_Click);
            this.button3.Click += new System.EventHandler(this.button_Click);
        }

        private void button_Click(object sender, EventArgs e)
        {
            Button button = (sender as Button);
            if (button != null)
            {
                label1.Text = string.Format("You pressed {0}", button.Text);
            }
        }
    }

您可以在设计模式下添加事件,并为每个事件选择相同的事件。我在构造函数中连接事件只是为了使它成为一个更明显的例子。

请注意,所有三个按钮单击处理程序都指向单个事件处理程序。该处理程序将查看事件的sender以查看按下了哪个按钮。然后只需获取按钮的标题,并将其显示在标签中的消息中。

您可以使用您正在创建的重复事件执行类似的操作(特别是在查看您添加到问题中的代码之后)。

答案 1 :(得分:0)

鼠标事件由Windows表单处理,因此需要在表单上完成实现,但是对于拖动事件,您可以让图片框实现IDropTarget接口,以便可以合并代码并为您提供一些重用更清洁的代码。