我在FlowLayoutPanel的ClientSizeChanged事件中调整子项大小时遇到FlowLayoutPanel问题。
当FlowLayoutPanel调整大小时,我试图让孩子们水平调整大小。问题是,即使子节点的边距为0并且FlowLayoutPanel的填充也为0,在执行ClientSizeChanged事件处理程序之后,FlowLayoutPanel会显示其水平滚动条 ,而子节点的宽度为与FlowLayoutPanel.ClientSize.Width完全相同 。
我已尝试将代码移至Resize事件,但我仍然得到相同的结果。
这是一个演示问题的示例,其中一个FlowLayoutPanel具有以下属性从默认值更改:
还有FlowLayoutPanel内的常规面板:
最后,一个间隔为1的计时器改变FlowLayoutPanel的宽度并在FlowLayoutPanel的HorizontalScroll.Visibile属性为true时禁用自身,并显示一个消息框,该消息框宣告了flow1的panel1和ClientSize.Width的宽度
以下是代码:
private void timer1_Tick(object sender, EventArgs e)
{
flow1.Width -= 1;
if (flow1.HorizontalScroll.Visible)
{
timer1.Enabled = false;
MessageBox.Show("Panel.Width = " + panel1.Width.ToString() +
", FlowPanel.ClientWidth = " + flow1.ClientSize.Width.ToString());
}
}
private void flow1_ClientSizeChanged(object sender, EventArgs e)
{
panel1.Width = flow1.ClientSize.Width;
}
当没有孩子溢出客户端大小时,显示水平滚动条背后的逻辑是什么?最重要的是,如何防止它发生?
答案 0 :(得分:1)
这是一个事件订单问题,布局过早计算。自动布局有几个讨厌的角落情况,它也可以是双稳态的,布局在两个解决方案之间来回翻转。您可以在测试应用中看到这一点,在MessageBox.Show()调用之前添加flow1.PerformLayout();
,您将看到滚动条再次被隐藏。
这就是SuspendLayout()
方法存在的原因。 Winforms程序员不能充分利用它。有充分理由,很难判断您何时需要它。他们真的不想要它。基本规则是,如果布局必须处理多个大小更改,则应使用它。
您的测试计划中真正的解决方法是什么:
private void timer1_Tick(object sender, EventArgs e) {
flow1.SuspendLayout();
flow1.Width -= 1;
flow1.ResumeLayout(true);
// etc..
}
你现在看到它工作正常,你永远不会看到消息框。