【问题标题】:Winform DragDrop Event EfficiencyWinform DragDrop 事件效率
【发布时间】:2014-01-10 20:15:42
【问题描述】:

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

以下是构造:

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

玩家骰子 —第二个面板与第一个面板的配置相同,并接受从掷骰子面板拖动的用户选择的骰子。我们的用例要求用户能够将骰子从 Rolled Dice 面板拖动到 Player Dice 面板,如果用户改变了他们想要保留的骰子的想法,则可以再次返回 - 一切都很好,这很好。

问题陈述 — 尽管我们可以将骰子从 Rolled Dice 面板拖到 Player Dice 面板(并在此过程中更新支持的 PictureBox 数组),但似乎有必要为两个面板中的 6 个 PictureBox 中的每一个拥有三个事件处理程序(MouseDown、DragEnter 和DragDrop),这相当于一大堆代码。

问题 — 有没有一种优雅的方式来为 ALL Rolled Dice 设置这 3 个事件处理程序中的一组,为 ALL Player Dice 设置一组这些事件处理程序,而不是像我们现在这样拥有一堆冗长的代码?

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

编辑: 这是我们为 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

【问题讨论】:

  • 你肯定夸大了“大量代码”,这些事件处理程序适用于所有图片框。但是你写的不够多,从资源管理器中拖一张图片看看它出错了。

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


【解决方案1】:

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

既然你不想要一个具体的答案,我给你一个一般的例子。采用这种简单的形式,带有三个按钮和一个标签:

现在,这个简单表单的代码如下(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 以查看按下了哪个按钮。然后它只获取按钮的标题,并将其显示在标签中的消息中。

您可以对您现在创建的重复事件执行类似的操作(尤其是在查看您添加到问题中的代码之后)。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 感谢您的建议!我们将研究 IDropTarget 接口及其实现。非常感谢。
    猜你喜欢
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多