Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MouseUp和MouseDown始终具有相同的对象发送器_C#_Winforms_Mouseevent_Minesweeper - Fatal编程技术网

C# MouseUp和MouseDown始终具有相同的对象发送器

C# MouseUp和MouseDown始终具有相同的对象发送器,c#,winforms,mouseevent,minesweeper,C#,Winforms,Mouseevent,Minesweeper,我正试图复制一艘扫雷舰,但我在鼠标事件方面遇到了麻烦。如果我按下picturebox上的鼠标按钮,然后将鼠标移动到另一个框中,mouseup事件仍将具有相同的对象发送器,即使它发生在另一个控件上 我需要mousedown事件,以便查看是否已按下两个鼠标按钮,不幸的是,mouseup事件似乎并不关心我释放按钮时光标在哪里 如果我表达不清楚,想想扫雷舰。我希望能够左键单击、右键单击、同时单击,并且能够在按下鼠标后移动光标并打开我释放的平铺 有人有什么想法吗?我想这样做: 创建子类按钮,以包含游戏资源

我正试图复制一艘扫雷舰,但我在鼠标事件方面遇到了麻烦。如果我按下picturebox上的鼠标按钮,然后将鼠标移动到另一个框中,mouseup事件仍将具有相同的对象发送器,即使它发生在另一个控件上

我需要mousedown事件,以便查看是否已按下两个鼠标按钮,不幸的是,mouseup事件似乎并不关心我释放按钮时光标在哪里

如果我表达不清楚,想想扫雷舰。我希望能够左键单击、右键单击、同时单击,并且能够在按下鼠标后移动光标并打开我释放的平铺

有人有什么想法吗?

我想这样做:

  • 创建子类按钮,以包含游戏资源作为它们的图片
  • 创建一个自定义控件,并根据需要添加尽可能多的按钮
  • 单击鼠标时,我将再次检查
    边界的
    包含方法
    以查看单击是否发生在该特定按钮上,或者以另一种方式处理自定义控件内的按钮单击
  • 如果我们看到你的一些代码,可能还有一个屏幕截图,那会更有帮助

    更新:

    这是一个如何使用委托处理单击的示例

    public partial class MineSweeper : UserControl
    {
        public MineSweeper()
        {
            InitializeComponent();
        }
    
        private void MineSweeper_Load(object sender, EventArgs e)
        {
            this.BackColor = Color.Red;
            for (int i = 0; i < 16; i++)
            {
                var button = new Button();
                button.Name = "Button" + i;
                button.Size = new Size(50, 50);
                button.ForeColor = Color.Yellow;
    
                button.ForeColor = Color.Black;
                button.Click += delegate
                {
                    MessageBox.Show("You have clicked me! I am " + button.Name);
                };
                flowLayoutPanel1.Controls.Add(button);
                flowLayoutPanel1.Invalidate();
            }
    
            this.Invalidate();
        }
    }
    
    公共部分类扫雷舰:用户控制
    {
    公共扫雷艇()
    {
    初始化组件();
    }
    私人空虚扫雷艇装载(目标发送者,事件参数e)
    {
    this.BackColor=Color.Red;
    对于(int i=0;i<16;i++)
    {
    var按钮=新按钮();
    button.Name=“button”+i;
    按钮尺寸=新尺寸(50,50);
    button.ForeColor=颜色.黄色;
    button.ForeColor=Color.Black;
    按钮。单击+=委派
    {
    MessageBox.Show(“您已单击我!我是”+按钮.名称);
    };
    flowLayoutPanel1.控件.添加(按钮);
    flowLayoutPanel1.Invalidate();
    }
    这个。使无效();
    }
    }
    

    只需从设计器中添加一个新的UserControl,向其添加一个flowLayoutPanel,并将其dock属性设置为full。

    我个人通过在每次MouseMove事件中更新一个表单级点变量来实现这一点。然后,当其他鼠标事件发生时,它们就有了最新的可用信息。

    我设法找到了一些方法,如果将来有人需要它,我会把它留在这里

    private void MouseUp(object sender, MouseEventArgs e)
        {
            Point ptCursor = Cursor.Position;
            ptCursor = PointToClient(ptCursor);
            PictureBox pBox = (PictureBox)GetChildAtPoint(ptCursor);
            pBox.BackColor = System.Drawing.Color.Blue;
        } 
    
    我用一些PictureBox设置了一个简单的表单,当鼠标点击事件发生时,它会检查光标位置下的控件,然后您可以根据需要使用它。我遇到的问题是mouseup事件与mousedown事件发生的控件绑定,因此我无法访问mouseup事件发生时光标所在的控件

    我只编程了大约4周,所以这个解决方案可能有很大的缺陷,所以如果有任何问题,一些反馈会很好。

    [VS 2017 c#]使用
    MouseEventArgs
    在鼠标向下/向上移动时的鼠标位置,只有在鼠标左键内捕捉到点时才有效,如下所示

    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
       //??? this changes at UP time and becomes same as MouseArgsUpPoint 
       //MouseArgsDownPoint = new Point(e.X, e.Y);
       //same as above, MouseArgsDownPoint = PointToClient(MousePosition);
    
       if (e.Button == MouseButtons.Left)
       {
           //inside here it works fine and Up/Down points are different and correct
           MouseArgsDownPoint = new Point(e.X, e.Y);
       }
    }
    
    
    private void Form1_MouseUp(object sender, MouseEventArgs e)
    {
        MouseArgsUpPoint = new Point(e.X, e.Y);
    }
    

    鼠标被
    控件捕获
    ,在该控件上发生了
    鼠标向下
    。是的,这就是问题所在,必须有某种方法来完成与原始扫雷艇相同的鼠标机制。原始扫雷艇没有对每个磁贴使用控件。它刚刚被画过。也许我应该检查一下点击的位置,计算一下点击了哪个磁贴,而不必为特定控件的事件操心。代码非常分散,但iv'e所做的是,我用存储在数组中的PictureBox创建了网格。我将每个磁贴下的内容存储在一个单独的数组中。我试着用pictureboxes mousedown和mouseup事件处理鼠标点击,但这会导致一些问题,因为它们的功能与扫雷舰中鼠标点击的功能不同。我需要的是一个click事件,它检查释放按钮时光标所在的控件,而不是第一次按下按钮时光标所在的位置。这个框不是吗?click会像winforms中的另一个click事件一样工作吗?主要的问题是我需要一个click方法,它忽略鼠标下降发生的位置,只关心鼠标下降发生的位置。@Lito在这种情况下,只需将
    click
    更改为
    MouseUp
    。我会花一些时间,粘贴一些代码和屏幕截图…我仍然很难弄清楚你真正需要什么。我认为FlowLayoutPanel将是错误的容器类型。扫雷舰是一个网格。开发商需要在各个方向都能方便地访问相邻的瓷砖。顺便说一句,如果你没有画任何东西,就没有理由调用那些
    Invalidate()
    方法。@LarsTech你说得很对,我只是用它来快速排列按钮。这意味着我必须根据光标坐标计算光标在哪个控件上,对吗?是的。因此,将它们设为8×像素或16×16。然后,对于8个像素,dox=e.locations.x>>3;对于16,e.Location.X>>4;它会自动为您提供索引。我应该补充一点,您还需要一个try-catch,因为如果您在没有picturebox的位置释放鼠标按钮,它将崩溃。最好明确检查
    GetChildAtPoint()
    的返回是否与picturebox类似
    var pBox=GetChildAtPoint(ptCursor);如果(pBox!=null){…}
    而不是使用
    尝试{…}catch{…}
    块。