C# C在SizeChanged事件期间修改表单大小
如果满足条件,我将在调整窗体大小时尝试设置窗体的高度。我将其设置为仅允许使用手动更改窗体的宽度 我有一个FlowLayoutPanel,显示一组PictureBox控件,每个控件的固定高度为50像素。最初,表单的高度是38 Size.Height-ClientSize.Height+50+6 Margin.Top+Margin.bottomofimage=94 如果控件溢出,默认情况下FlowLayoutPanel会将它们向下推到新行上。我想做的是在这种情况下调整窗体的大小,或者手动更改窗体宽度,这可能会导致控件跳转到下一行 以下代码有效,并在将新控件添加到FlowLayoutPanel itemPanel时调用:C# C在SizeChanged事件期间修改表单大小,c#,winforms,resize,C#,Winforms,Resize,如果满足条件,我将在调整窗体大小时尝试设置窗体的高度。我将其设置为仅允许使用手动更改窗体的宽度 我有一个FlowLayoutPanel,显示一组PictureBox控件,每个控件的固定高度为50像素。最初,表单的高度是38 Size.Height-ClientSize.Height+50+6 Margin.Top+Margin.bottomofimage=94 如果控件溢出,默认情况下FlowLayoutPanel会将它们向下推到新行上。我想做的是在这种情况下调整窗体的大小,或者手动更改窗体宽度
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事件,但我不知道如何解决此问题。当我打印出lastElement.Bottom+lastElement.Margin.Bottom和itemPanel.Height的值时,设置高度后,它们是相同的,但代码仍然以某种方式达到了这一点
简而言之,我只希望手动更改表单宽度,但在添加项目或更改宽度时,表单的高度会更改,以便可以查看FlowLayoutPanel内的所有控件。尝试一下:
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
}
但是,当在my SizeChange事件中调用时,此方法会导致
要在初始高度和新高度之间闪烁的窗体
基本上,表单的任何库存调整事件都将发生得太晚,您无法在不被注意的情况下更改大小
您将要捕获该消息:
发送到用户正在调整大小的窗口。通过处理这个
消息,应用程序可以监视拖动的大小和位置
矩形,如果需要,更改其大小或位置
这将允许您在窗体在屏幕上实际更新之前更改窗体的大小
它看起来像这样:
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;
}
}
}
这不管用。我决定采用“空闲思维”的解决方案。谢谢这太好笑了。我决定再试一次,看看是否有答案,我想出的解决办法就是这样!我正要回答我自己的问题,这时我看到你这样做了,所以我会接受你的回答。谢谢
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;
}
}
}