简体   繁体   English

C#单击源检测

[英]C# Click source detection

I have a GroupBox that has multiple controls, specifically 4 PictureBoxes . 我有一个具有多个控件的GroupBox ,尤其是4 PictureBoxes 在此处输入图片说明

These are pieces of an image puzzle. 这些是图像拼图的一部分。 Please note that the number of images can change. 请注意,图像数量可能会改变。 I want to allow a drag and drop effect to each of them. 我希望对每个对象都具有拖放效果。 To mark the source and the destination I did the following: 为了标记源和目标,我执行了以下操作:

foreach (var box in boxes)
{
    box.DragEnter += new DragEventHandler(box_DragEnter);
    box.MouseDown += new MouseEventHandler(box_MouseDown);
    box.DragDrop += new DragEventHandler(box_DragDrop);
    box.AllowDrop = true;
}

When a box is clicked it will be marked to a global variable (that will be the source) and when a box raises the DragDrop event that will be the destination. 当单击一个框时,它将被标记为全局变量(将作为源变量),并且当框引发DragDrop事件(将作为目标)时。

As I previously mentioned, since the number of the boxes can be changed I do not want to add separate methods as handlers for each event. 如前所述,由于可以更改框的数量,因此我不想为每个事件添加单独的方法作为处理程序。

My issue here is that I do not know how to "detect" which box has raised what event. 我的问题是,我不知道如何“检测”哪个框引发了什么事件。

Example: 例:

*If I press on the left-top image I want to know that I pressed on it to mark the source (let's say global picSource = 1) and if I drop on right-bottom image I want to know that as a destination (picDestination = 4). *如果我按左上方的图像,我想知道我按了它以标记源(假设全局picSource = 1),如果我放到右下方的图像,我想知道这是目的地(picDestination = 4)。 All that must occur in the handlers. 所有这些必须在处理程序中发生。 * *

Tests: 测试:

  • Adding a parent panel (same size as the GroupBox) with a Click event & doing a comparison between a Point issued with the X&Y provided by the event handler and a rectangle designated with the X,Y, width, height of the panel. 添加带有Click事件的父面板(与GroupBox大小相同),并在事件处理程序提供的X&Y和由面板的X,Y,宽度,高度指定的矩形之间进行比较。
  • Adding handlers to the GroupBox (does not work either) 将处理程序添加到GroupBox(也不起作用)

Notes: 笔记:

  • eX and eY refer to the position of the mouse eX和eY指的是鼠标的位置

    void box_MouseDown(object sender, MouseEventArgs e) 无效的box_MouseDown(对象发送者,MouseEventArgs e)

  • The purpose of this is to switch boxes (source <--> destination) 这样做的目的是切换框(源<->目标)

You can just detect puzzle element by mouse's coordinates in the controls container's MouseDown and MouseUp event as follows: 您只需在控件容器的MouseDownMouseUp事件中通过鼠标的坐标检测拼图元素,如下所示:

public partial class PuzzleForm : Form
{
    private readonly Image[,] Images;
    private readonly int Nx;
    private readonly int Ny;
    private int sourceIndexX;
    private int sourceIndexY;
    private int destinationIndexX;
    private int destinationIndexY;

    private PuzzleForm()
    {
        SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw, true);
        InitializeComponent();
    }

    public PuzzleForm(Image[,] images)
        : this()
    {
        Images = images;
        Nx = Images.GetLength(0);
        Ny = Images.GetLength(1);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        using (Graphics g = e.Graphics)
        {
            for (int j = 0; j < Ny; j++)
                for (int i = 0; i < Nx; i++)
                {
                    Rectangle rect = new Rectangle(ClientSize.Width * i / Nx, ClientSize.Height * j / Ny, ClientSize.Width / Nx - 1, ClientSize.Height / Ny - 1);
                    g.DrawImage(Images[i, j], rect);
                }
        }
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);

        if (e.Button != MouseButtons.Left)
            return;

        sourceIndexX = e.X * Nx / ClientSize.Width;
        sourceIndexY = e.Y * Ny / ClientSize.Height;

        Cursor = Cursors.Hand;
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        base.OnMouseUp(e);

        if (e.Button != MouseButtons.Left)
            return;

        destinationIndexX = e.X * Nx / ClientSize.Width;
        destinationIndexY = e.Y * Ny / ClientSize.Height;

        Cursor = Cursors.Default;

        if (sourceIndexX != destinationIndexX || sourceIndexY != destinationIndexY)
        {
            swapImages();
            MessageBox.Show(String.Format("From [{0}, {1}] to [{2}, {3}]", sourceIndexX, sourceIndexY, destinationIndexX, destinationIndexY));
        }
    }

    private void swapImages()
    {
        Image tmp = Images[sourceIndexX, sourceIndexY];
        Images[sourceIndexX, sourceIndexY] = Images[destinationIndexX, destinationIndexY];
        Images[destinationIndexX, destinationIndexY] = tmp;
        Invalidate();
    }
}

Usage: 用法:

Image[,] images = new Image[2, 2];
// Fill array with images:
images[0, 0] = Bitmap.FromFile(@"..."); 
images[0, 1] = Bitmap.FromFile(@"...");
images[1, 0] = Bitmap.FromFile(@"...");
images[1, 1] = Bitmap.FromFile(@"...");

PuzzleForm puzzleForm = new PuzzleForm(images);
// Show form or whatever you want.
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM