简体   繁体   中英

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).

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.

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. 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:

    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 );
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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