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