C# 检查一个控件是否位于另一个控件之上

C# 检查一个控件是否位于另一个控件之上,c#,winforms,panel,C#,Winforms,Panel,我一直想做一个拖放游戏。我有4个面板和4个标签。必须将标签拖到正确的面板顶部 问题在于检查标签是否位于面板顶部。用户可以自由拖动标签 private void button1_MouseMove(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { button1.Left = e.X + button

我一直想做一个拖放游戏。我有4个面板和4个标签。必须将标签拖到正确的面板顶部

问题在于检查标签是否位于面板顶部。用户可以自由拖动标签

private void button1_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            button1.Left = e.X + button1.Left - MouseDownLocation.X;
            button1.Top = e.Y + button1.Top - MouseDownLocation.Y;
        }
    }

    private void button1_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            MouseDownLocation = e.Location;
        }
    }
这是我用来移动控件的代码。我必须提到,这是一个测试项目,所以我使用了一个按钮而不是标签,但想法是一样的


有没有办法检查一个控件是否位于另一个控件之上

要检查鼠标是否在控件上,可以检查
光标.Position
是否位于控件的
ClientRectangle
中,但首先需要调用控件的
PointToClient
方法来转换光标相对于面板的
(0,0)
的位置,例如:

var b = panel1.ClientRectangle.Contains(panel1.PointToClient(Cursor.Position));
if(b) panel1.BackColor = Color.Red; else panel1.BackColor = Color.Gray;
可以在用于移动控件的同一事件处理程序中检查该标志,例如:

var b = panel1.ClientRectangle.Contains(panel1.PointToClient(Cursor.Position));
if(b) panel1.BackColor = Color.Red; else panel1.BackColor = Color.Gray;

要检查鼠标是否在控件上,可以检查
光标.Position
是否位于控件的
ClientRectangle
,但首先需要调用控件的
PointToClient
方法来转换光标相对于面板的
(0,0)
的位置,例如:

var b = panel1.ClientRectangle.Contains(panel1.PointToClient(Cursor.Position));
if(b) panel1.BackColor = Color.Red; else panel1.BackColor = Color.Gray;
可以在用于移动控件的同一事件处理程序中检查该标志,例如:

var b = panel1.ClientRectangle.Contains(panel1.PointToClient(Cursor.Position));
if(b) panel1.BackColor = Color.Red; else panel1.BackColor = Color.Gray;

每次移动后,只需从按钮和面板的属性中获取矩形,然后使用或:


每次移动后,只需从按钮和面板的属性中获取矩形,然后使用或:


你认为标签在面板的顶部什么时候可以复制?当它在面板上完成或者仅仅是一小部分时,你所控制的控件不是总是在顶部的吗?可能的复制品是什么时候你认为标签在面板的顶部?当它在面板上完成或只是一小部分时?你移动的控件不是总是在顶部吗?你似乎忘记了何时/何地检查此条件:)因为OP不是真正拖动对象,而是移动控件,当光标位于其他控件的客户端区域(IIRC)上时,其他控件不会引发MouseEnter/MouseMove事件。@Jimi不需要其他控件事件处理程序;可以在OP用于移动控件的同一事件处理程序中检查该标志。类似于
if(b)panel1.BackColor=Color.Red;else panel1.BackColor=颜色。灰色。是的,当然。但这并不能确定移动对象和正确容器之间的关系。假设有10个标签(而不是4个)必须在10个不同的面板内移动,并且必须确定标签是否位于右侧面板内。此外,假设使面板成为右侧面板的是一个随机条件(即,一个单词(文本)需要与另一个单词(文本)耦合)。如果
Label1
的右面板始终是
Panel1
。@Jimi假设我们有一个非常复杂的函数,如
Panel GetPanel(Label)
,它返回标签的右面板,那么问题再次简化为检查鼠标是否在特定控件上。然后上面的代码只需要
var panel1=GetPanel((标签)sender)在变量b=…
之前。对吗?另外,由于控件可能不在同一个容器中,例如标签位于一个组框中,而面板位于另一个组框中,因此我会通过以下方式检查相交或包含:
var b=panel1.Parent.RectangleToScreen(panel1.Bounds).IntersectsWith(label1.Parent.RectangleToScreen(label1.Bounds))您似乎忘记了何时/何地检查此条件:)由于OP不是真正拖动对象,而是四处移动控件,因此当光标位于其客户端区域(IIRC)上时,其他控件不会引发MouseEnter/MouseMove事件。@Jimi不需要其他控件事件处理程序;可以在OP用于移动控件的同一事件处理程序中检查该标志。类似于
if(b)panel1.BackColor=Color.Red;else panel1.BackColor=颜色。灰色。是的,当然。但这并不能确定移动对象和正确容器之间的关系。假设有10个标签(而不是4个)必须在10个不同的面板内移动,并且必须确定标签是否位于右侧面板内。此外,假设使面板成为右侧面板的是一个随机条件(即,一个单词(文本)需要与另一个单词(文本)耦合)。如果
Label1
的右面板始终是
Panel1
。@Jimi假设我们有一个非常复杂的函数,如
Panel GetPanel(Label)
,它返回标签的右面板,那么问题再次简化为检查鼠标是否在特定控件上。然后上面的代码只需要
var panel1=GetPanel((标签)sender)在变量b=…
之前。对吗?另外,由于控件可能不在同一个容器中,例如标签位于一个组框中,而面板位于另一个组框中,因此我会通过以下方式检查相交或包含:
var b=panel1.Parent.RectangleToScreen(panel1.Bounds).IntersectsWith(label1.Parent.RectangleToScreen(label1.Bounds))正如您所知,此代码假定正在比较的两个控件位于同一容器中。如果它们不是,您可以将坐标转换为屏幕坐标,然后进行比较。正如您所知,此代码假定两个被比较的控件位于同一容器中。如果不是,您可以将坐标转换为屏幕坐标,然后进行比较。