#c# #winforms #resize #window-resize
#c# #winforms #изменение размера #окно-изменение размера
Вопрос:
Я хочу разрешить любую высоту формы, но только определенную ширину (300, 550 , 800, …( 250)). Я попробовал этот код:
Resize = (s, a) => {
if (Width < 425)
Width = 300;
else if (Width < 675)
Width = 550;
else if (Width < 925)
Width = 800;
else ...
};
Когда я пытаюсь изменить размер своей формы, граница колеблется между положением мыши и ожидаемой шириной. Как я могу добиться такого поведения?
Ответ №1:
Я думаю, проблема в том, что вы делаете это в Resize
событии, поэтому, как только мышь начинает двигаться, событие срабатывает, и ваш код изменяет размер формы.
Вместо этого попробуйте использовать ResizeEnd
событие, которое срабатывает только после того, как пользователь прекращает изменять размер:
ResizeEnd = (s, a) =>
{
var widths = new[] {300, 550, 800, 1050, 1300, 1550, 1800};
Width = widths.First(w => Width < w 125);
};
Комментарии:
1. Вот так. Прошло некоторое время с тех пор, как я работал в Winforms
2. Почти решение. Было бы лучше, если бы форма резко изменялась с 300 пикселей до 550 пикселей, с 1 столбца данных до 2 столбцов фиксированного размера
3. Я думал, что это то, что ваш код уже сделал, но вы не хотели, чтобы он изменялся? Пожалуйста, проясните вопрос. Что не работает с вашим кодом, и какое поведение вы хотите видеть вместо этого?
4. «Я думал, что это то, что ваш код уже сделал, но вы не хотели, чтобы он изменялся?». Да, это так.
Ответ №2:
Изменение размера или событие BeforeResize для формы
Для управления размером формы, ResizeEnd или SizeChanged немного запаздывают, и если вы хотите изменить размер в этих событиях, это приводит к мерцанию.
Чтобы обработать изменение размера до применения нового размера, вы можете отправить сообщение WM-SIZING, которое включает предлагаемый размер и край формы, который вызвал изменение размера.
В следующем примере я установил размер плитки для формы и попытался изменить размер на основе плиток:
private int widthGridSize = 200;
private int heightGridSize = 1;
private const int WM_SIZING = 0x0214;
enum EdgeType : int
{
WMSZ_LEFT = 1,
WMSZ_RIGHT = 2,
WMSZ_TOP = 3,
WMSZ_TOPLEFT = 4,
WMSZ_TOPRIGHT = 5,
WMSZ_BOTTOM = 6,
WMSZ_BOTTOMLEFT = 7,
WMSZ_BOTTOMRIGHT = 8
}
[StructLayout(LayoutKind.Sequential)]
public class RECT
{
public int L, T, R, B;
public int W => R - L;
public int H => B - T;
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_SIZING)
{
var flag = (EdgeType)m.WParam;
var rect = new RECT();
Marshal.PtrToStructure(m.LParam, rect);
var w = (int)Math.Round((double)rect.W / widthGridSize) * widthGridSize;
var h = (int)Math.Round((double)rect.H / heightGridSize) * heightGridSize;
switch (flag)
{
case EdgeType.WMSZ_LEFT:
rect.L = rect.R - w;
break;
case EdgeType.WMSZ_RIGHT:
rect.R = rect.L w;
break;
case EdgeType.WMSZ_TOP:
rect.T = rect.B - h;
break;
case EdgeType.WMSZ_TOPLEFT:
rect.T = rect.B - h;
rect.L = rect.R - w;
break;
case EdgeType.WMSZ_TOPRIGHT:
rect.T = rect.B - h;
rect.R = rect.L w;
break;
case EdgeType.WMSZ_BOTTOM:
rect.B = rect.T h;
break;
case EdgeType.WMSZ_BOTTOMLEFT:
rect.B = rect.T h;
rect.L = rect.R - w;
break;
case EdgeType.WMSZ_BOTTOMRIGHT:
rect.B = rect.T h;
break;
default:
break;
}
Marshal.StructureToPtr(rect, m.LParam, true);
m.Result = (IntPtr)1;
}
else
base.WndProc(ref m);
}