You want to move the control so that it does not go beyond the boundaries of the form. With the left border, tracking the achievement of the border turned out to be easy

if (PointToClient(p).X >= 0){/*код*/ } 

But when I try to do this:

 int w = ActiveForm.Size.Width; if (PointToClient(p).X <= w){/*код*/ } 

the element still goes beyond the right border. That is, Size.Width is not the right border of the form.

In this regard, the question: how to determine the right border?

    3 answers 3

    As a response, I can offer a simple, “in the forehead,” but still a solution in the form of an SLN .

    There, a socket simply runs on the form, starting from the edges of the form and the top panel and checking if the coordinates of the control (panel) are outside the set boundaries.

    Demo for the question

    The code itself:

     using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using System.Threading; namespace RightMargin { /// <summary> /// Description of MainForm. /// </summary> public partial class MainForm : Form { public bool MoveActive { get; set; } public int deltaX { get; set; } public int deltaY { get; set; } public MainForm() { InitializeComponent(); MoveActive = false; deltaX = 1; deltaY = 1; } void buttonCloseClick(object sender, EventArgs e) { MoveActive = false; Close(); } void ButtonStartClick(object sender, EventArgs e) { MoveActive = true; while (MoveActive) { int newX = boxPanel.Left + deltaX; int newY = boxPanel.Top + deltaY; int maxX = ActiveForm.ClientSize.Width - boxPanel.Size.Width - 1; int maxY = ActiveForm.ClientSize.Height - boxPanel.Size.Height - 1; //Проверка координат if (newX < 0) { newX = 0; deltaX = -deltaX; } if (newY < panelMenu.Size.Height) { newY = panelMenu.Size.Height; deltaY = -deltaY; } if (newX > maxX) { newX = maxX; deltaX = -deltaX; } if (newY > maxY) { newY = maxY; deltaY = -deltaY; } boxPanel.Left = newX; boxPanel.Top = newY; //Thread.Sleep(2); Application.DoEvents(); } } void ButtonStopClick(object sender, EventArgs e) { MoveActive = false; } } } 
    • one
      It is not good to push the main application code into the event handler code, besides in an infinite loop. Glitch is - the stop button is triggered only by the second click. Instead of Thread.Sleep , which you have commented out, it was better to use a timer, use the buttons to start and stop it, and to call a separate method for moving the panel according to a timer event. - rdorn

    The right border is determined correctly. You just check the visibility of one particular point - the upper left corner of the control.

    In addition, the check is also not strict, which captures one pixel outside the right border (since the coordinates lie in the range 0 ≤ x <(width) due to counting from zero).

    Finally, it makes sense to check the position of the left border of an element relative to zero, and the position of the right one relative to the width of the form.

    • five
      well and ActiveForm.ClientSize.Width use - 4per

    Your question is more about math than programming. But since one without the other does not work, I will sign in detail.

    Go. The position of the control on the form and the form on the screen is set by the position of the upper left corner and the Control.Location property (the red dot in the figure below). The position of the remaining angles can be calculated by adding the length and / or width of the control, which is specified in the Control.Size property, to the Control.Location coordinates.

    enter image description here

    So that the control always remains entirely within the boundaries of the parent control (the form is also control), the coordinate values Control.Location should not go beyond the boundary of the green area in the figure. The dimensions of this area are easy to calculate from the dimensions of the control and the parent control.

    It remains to consider only one moment. The control can have a specific frame style, which is especially important for the form. The Control.Size property sets the external dimensions of the control, so if you use them to determine the available drawing area, then the child control will fall under the frame or header of the form. This is not the result that you want to see. To take into account the dimensions of the controls, frames, headers, etc., the Control.ClientSize property is defined, which contains the actual size of the area available for drawing the child elements (read the captions in the figure carefully).