简体   繁体   English

C#WinForms:通过拖动子PictureBox控件拖放父控件

[英]C# WinForms : Drag and Drop Parent Control by Dragging Child PictureBox Control

Note: Question Title and text changed. 注意:问题标题和文本已更改。 I realized I had asked the wrong question for my needs. 我意识到我根据自己的需求提出了错误的问题。

I have a problem I can't solve. 我有一个我无法解决的问题。 I have a picturebox on a user control: 我在用户控件上有一个图片框:

用户控件上的PictureBox(pbxMoveIt)

Clicking on the parent allows me to drag the entire control (I can click and drag it anywhere on the WinForm). 单击父级可以拖动整个控件(可以单击并将其拖动到WinForm上的任何位置)。

I need to be able to drag the parent control by clicking and dragging the picture box (child control). 我需要能够通过单击并拖动图片框(子控件)来拖动父控件。

The picturebox should never be moved within the parent control. 图片框绝对不能在父控件中移动。 Clicking the child control and dragging needs to move the parent and the children controls without changing their position within the parent control. 单击子控件并拖动需要移动父控件和子控件,而无需更改其在父控件中的位置。

I've tried putting together what I've seen online, but I'm missing something. 我尝试将在线观看的内容整理在一起,但我缺少了一些东西。 The code below has separate events in the WinForm for handling the user control and user control's children. 下面的代码在WinForm中具有单独的事件,用于处理用户控件和用户控件的子级。

public partial class frmMain : Form {

    private Point m_MouseDownLocation;
    private bool m_IsDragging;
    public frmMain ( ) {
        InitializeComponent ( );

        suc1.MouseDown += SimpleUserControl_MouseDown;
        suc1.MouseMove += SimpleUserControl_MouseMove;
        suc1.MouseUp += SimpleUserControl_MouseUp;
        suc1.PbxMoveIt.MouseDown += SimpleUserChildControl_MouseDown;
        suc1.PbxMoveIt.MouseMove += SimpleUserChildControl_MouseMove;
        suc1.PbxMoveIt.MouseUp += SimpleUserChildControl_MouseUp;
    }

    #region SimpleUserControl Related
    private void SimpleUserControl_MouseDown ( object sender, MouseEventArgs e ) {
        if ( e.Button == MouseButtons.Left ) {
            m_MouseDownLocation = e.Location;
            m_IsDragging = true;
            suc1.DisableButton ( );
        }
    }
    private void SimpleUserControl_MouseMove ( object sender, MouseEventArgs e ) {
        int newX;
        int newY;
        int minX = 10;
        int minY = 10;
        int maxX = this.Width - (25 + suc1.Width);
        int maxY = this.Height - (45 + suc1.Height);
        if ( e.Button == MouseButtons.Left ) {
            newX = e.X + suc1.Left - m_MouseDownLocation.X;
            newY = e.Y + suc1.Top - m_MouseDownLocation.Y;
            if ( m_IsDragging ) {
                if ( ( newX >= minX ) && ( newX <= maxX ) ) {
                    suc1.Left = newX;
                }
                if ( ( newY >= minY ) && ( newY <= maxY ) ) {
                    suc1.Top = newY;
                }
            }
        }
    }

    private void SimpleUserControl_MouseUp ( object sender, MouseEventArgs e ) {
        if ( e.Button == MouseButtons.Left ) {
            m_IsDragging = false;
            suc1.EnableButton ( );
        }
    }
    #endregion

    #region Simple User Child Control Related
    private void SimpleUserChildControl_MouseDown ( object sender, MouseEventArgs e ) {
        SimpleUserControl useThis = (SimpleUserControl)((Control)sender).Parent;
        if ( e.Button == MouseButtons.Left ) {
            m_MouseDownLocation = e.Location;
            m_IsDragging = true;
            useThis.DisableButton ( );
        }
    }
    private void SimpleUserChildControl_MouseMove ( object sender, MouseEventArgs e ) {
        SimpleUserControl useThis = (SimpleUserControl)((Control)sender).Parent;
        int newX;
        int newY;
        int minX = 10;
        int minY = 10;
        int maxX = useThis.Width - (25 + useThis.Width);
        int maxY = useThis.Height - (45 + useThis.Height);
        if ( e.Button == MouseButtons.Left ) {
            newX = e.X + useThis.Left - m_MouseDownLocation.X;
            newY = e.Y + useThis.Top - m_MouseDownLocation.Y;
            if ( m_IsDragging ) {
                if ( ( newX >= minX ) && ( newX <= maxX ) ) {
                    useThis.Left = newX;
                }
                if ( ( newY >= minY ) && ( newY <= maxY ) ) {
                    useThis.Top = newY;
                }
            }
        }
        if ( e.Button == MouseButtons.Right ) {
            MessageBox.Show ( "Right Button Clicked!" );
        }
    }
    private void SimpleUserChildControl_MouseUp ( object sender, MouseEventArgs e ) {
        SimpleUserControl useThis = (SimpleUserControl)((Control)sender).Parent;
        if ( e.Button == MouseButtons.Left ) {
            m_IsDragging = false;
            useThis.EnableButton ( );
        }
    }
    #endregion
}

Doing a bit of digging, I discovered the answer. 经过一些挖掘,我找到了答案。 Since the answers I saw on the internet didn't explain the concepts, I'm including that in the answer. 由于我在互联网上看到的答案并未解释这些概念,因此将其包含在答案中。 Hopefully that will help the next person asking the question. 希望这将有助于下一个提出问题的人。

Answer Concept: 答案概念:

The problem is the Child Control's behavior (ie events) "catch" the event before it can affect the Parent Control. 问题在于子控件的行为(即事件)会在影响父控件之前“捕获”该事件。

The behavior of the Child Control needs to link the behavior of the Parent Control to it. 子控件的行为需要将父控件的行为与其链接起来。 This means using the related events in the Child Control to call the same event in the Parent. 这意味着使用子控件中的相关事件在父控件中调用同一事件。

However, since the events need to affect the Parent Control, the code for the Child Control must exist in the Parent Control (see code example below). 但是,由于事件需要影响父控件,因此子控件的代码必须存在于父控件中(请参见下面的代码示例)。

The best way to think of this is the code has to reside in the context of effect. 想到这一点的最好方法是代码必须驻留在效果上下文中。 In other words, if you want to effect the Parent Control using Child Control code, the said code should reside in the Parent Controls code. 换句话说,如果您想使用“子控件”代码来实现“父控件”,则所述代码应驻留在“父控件”代码中。

Coding Specifics: 编码细节:

The related events are MouseDown, MouseMove, and MouseUp. 相关事件是MouseDown,MouseMove和MouseUp。 To link the events from the Child to the Parent: 要将事件从孩子链接到父母:

  1. Create code for the Child events in the Parent's code. 在父代代码中为子代事件创建代码。
  2. Assign the code for the Child events to the Child Control in the Parent 将子事件的代码分配给父级中的子控件

Here's the example code for the Child events as defined in the Parent code (note this.MouseX links the Child event MouseX to the Parent event MouseX: 这是在父代码中定义的子事件的示例代码(请注意此.MouseX将子事件MouseX链接到父事件MouseX:

    public void ChildControl_MouseDown ( object sender, MouseEventArgs e ) {
        if ( e.Button == MouseButtons.Right ) {
            MessageBox.Show ( "Huzzah!" );
        }
        if ( e.Button == MouseButtons.Left ) {
            //MessageBox.Show ( "Booyah!" );
            this.OnMouseDown ( e );
        }
    }
    public void ChildControl_MouseMove ( object sender, MouseEventArgs e ) {
        if ( e.Button == MouseButtons.Left ) {
            this.OnMouseMove ( e );
        }
    }
    public void ChildControl_MouseUp ( object sender, MouseEventArgs e ) {
        if ( e.Button == MouseButtons.Left ) {
            this.OnMouseUp ( e );
        }
    }

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

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