如果符合条件,我正在尝试设置表单的高度,而我正在调整表单的高度。我将其设置为仅允许使用this link手动更改表单的宽度。
我有一个FlowLayoutPanel,显示一组PictureBox控件,每个控件都有一个50像素的固定高度。最初,表单的高度为38(Size.Height - ClientSize.Height)+ 50 + 6(Margin.Top + Margin.Bottom of image)= 94.
如果控件溢出,默认情况下,FlowLayoutPanel会将它们向下推到新行。我想要做的是在发生这种情况时调整表单大小,或者手动更改表单宽度,这可能会导致控件跳转到下一行。
以下代码有效,只要将新控件添加到FlowLayoutPanel(itemPanel),就会调用该代码:
private void ResizeForm()
{
if (itemPanel.Controls.Count < 1) return;
var lastElement = itemPanel.Controls[itemPanel.Controls.Count - 1];
// The Form is the correct size, no need to resize it:
if (lastElement.Bottom + lastElement.Margin.Bottom == itemPanel.Height) return;
Height = 38 + lastElement.Bottom + lastElement.Margin.Bottom;
}
但是,在我的SizeChange事件中调用时,此方法会导致Form在初始高度和新高度之间“闪烁”:
private void MainForm_SizeChanged(object sender, EventArgs e)
{
ResizeForm();
}
我猜是因为设置Height会再次触发SizeChange事件,但我不知道如何解决这个问题。在设置高度后打印出lastElement.Bottom + lastElement.Margin.Bottom
和itemPanel.Height
的值时,它们是相同的,但代码仍然以某种方式达到了这一点。
简而言之,我希望仅表单宽度手动更改,但是在添加项目或更改宽度时要更改的表单高度,这样就可以查看FlowLayoutPanel中的所有控件。
答案 0 :(得分:0)
但是,在我的SizeChange事件中调用时,此方法会导致 表格到&#34; flash&#34;在初始高度和新高度之间
基本上任何股票&#34;调整大小&#34;您的表格的事件发生得太晚,您无法在不明显的情况下更改大小。
您想要捕获WM_SIZING消息:
发送到用户正在调整大小的窗口。通过处理这个 消息,应用程序可以监视拖动的大小和位置 矩形,如果需要,可以改变它的大小或位置。
这样您就可以在屏幕上实际更新>之前更改表单的大小。
它看起来像这样:
public partial class Form1 : Form
{
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
enum HitTest
{
Caption = 2,
Transparent = -1,
Nowhere = 0,
Client = 1,
Left = 10,
Right = 11,
Top = 12,
TopLeft = 13,
TopRight = 14,
Bottom = 15,
BottomLeft = 16,
BottomRight = 17,
Border = 18
}
private const int WM_SIZING = 0x214;
private const int WM_NCHITTEST = 0x84;
public Form1()
{
InitializeComponent();
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
switch (m.Msg)
{
case WM_NCHITTEST:
var result = (HitTest)m.Result.ToInt32();
if (result == HitTest.Top || result == HitTest.Bottom)
m.Result = new IntPtr((int)HitTest.Caption);
if (result == HitTest.TopLeft || result == HitTest.BottomLeft)
m.Result = new IntPtr((int)HitTest.Left);
if (result == HitTest.TopRight || result == HitTest.BottomRight)
m.Result = new IntPtr((int)HitTest.Right);
break;
case WM_SIZING:
// Retrieve the "proposed" size of the Form in "rc":
RECT rc = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
// ... do something with "rc" ...
// this is your code (slightly modified):
if (itemPanel.Controls.Count > 0)
{
var lastElement = itemPanel.Controls[itemPanel.Controls.Count - 1];
if (lastElement.Bottom + lastElement.Margin.Bottom != itemPanel.Height)
{
int Height = 38 + lastElement.Bottom + lastElement.Margin.Bottom;
rc.Bottom = rc.Top + Height; // <--- use "Height" to update the "rc" struct
}
}
// Put the updated "rc" back into message structure:
Marshal.StructureToPtr(rc, m.LParam, true);
break;
}
}
}
答案 1 :(得分:-1)
尝试一下:
private void ResizeForm()
{
this.SuspendLayout(); // Suspends the layout logic until ResumeLayout() is called (below)
if (itemPanel.Controls.Count < 1) return;
var lastElement = itemPanel.Controls[itemPanel.Controls.Count - 1];
// The Form is the correct size, no need to resize it:
if (lastElement.Bottom + lastElement.Margin.Bottom == itemPanel.Height) return;
Height = 38 + lastElement.Bottom + lastElement.Margin.Bottom;
this.ResumeLayout(); // ADD THIS AS WELL
}