Страницы

Поиск по вопросам

среда, 12 февраля 2020 г.

Как правильно определить правую границу формы?

#c_sharp #winforms


Требуется перемещать элемент управления так, чтобы он не выходил за границы формы.
С левой границей отследить достижение границы оказалось легко:

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


Но когда я пытаюсь сделать так:

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


элемент всё равно уходит за правую границу. Т. е. Size.Width - это не правая граница
формы.

В связи с этим вопрос: как определить правую границу?
    


Ответы

Ответ 1



В качестве ответа могу предложить простое, «в лоб», но всё же решение в виде SLN. Там просто на форме бегает панелька, отталкиваясь от краев формы и верхней панели и проверяя, не выходят ли координаты контрола (панели) за установленные границы. Сам код: using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using System.Threading; namespace RightMargin { /// /// Description of MainForm. /// 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; } } }

Ответ 2



Ваш вопрос относится больше к математике, чем программированию. Но так как одно без другого не работает, распишу подробно. Поехали. Положение контрола на форме и формы на экране задается положением левого верхнего угла и свойством Control.Location (красная точка на рисунке ниже). Положение остальных углов может быть вычислено добавлением длины и/или ширины контрола, которые заданы в свойстве Control.Size, к координатам Control.Location. Таким образом, чтобы контрол всегда целиком оставался в границах родительского контрола (форма тоже контрол), значения координат Control.Location не должны выходить за границу зеленой области на рисунке. Размеры этой области несложно вычислить из размеров контрола и родительского контрола. Остается учесть только один момент. У контрола может быть задан определенный стиль рамки, особенно это важно для формы. Свойство Control.Size задает внешние размеры контрола, поэтому если использовать их для определения доступной области рисования, то дочерний контрол будет попадать под рамку или шапку формы. Это не тот результат который хочется видеть. Для учета размеров оформления контрола, рамок, шапки и т.д., определено свойство Control.ClientSize, которое содержит актуальный размер области, доступной для отрисовки дочерних элементов (внимательно читаем подписи на рисунке).

Ответ 3



Правая граница определяется верно. Просто вы проверяете видимость одной конкретной точки — верхнего левого угла элемента управления. В придачу, проверка ещё и не строгая, захватывающая один пиксель за пределами правой границы (так как координаты лежат в диапазоне 0 ≤ x < (width) из-за отсчёта с нуля). Наконец, имеет смысл проверять положение левой границы элемента относительно нуля, а положение правой — относительно ширины формы.

Комментариев нет:

Отправить комментарий