Delphi 基于流面板内容计算流面板宽度

Delphi 基于流面板内容计算流面板宽度,delphi,resize,flowpanel,Delphi,Resize,Flowpanel,我正在将帧动态填充到流面板中(作为水平方向VCL Metropolis应用程序的一部分)。我需要调整每个组的“流”面板的大小,使其水平适合所有项目。我有一个非常简单的公式,它有时会起作用,但并非总是如此——特别是在添加奇数项时。流程面板的FlowStyle设置为fsTopBottomLeftRight并垂直安装两个框架 例如,添加7个项目会自动检测正确的宽度(4个项目)。但是,添加5个项目并不能检测到正确的宽度(假定宽度为3,但最终检测到宽度为2) 如何正确计算每组的宽度 以下是将项目填充到每个

我正在将帧动态填充到流面板中(作为水平方向VCL Metropolis应用程序的一部分)。我需要调整每个组的“流”面板的大小,使其水平适合所有项目。我有一个非常简单的公式,它有时会起作用,但并非总是如此——特别是在添加奇数项时。流程面板的
FlowStyle
设置为
fsTopBottomLeftRight
并垂直安装两个框架

例如,添加7个项目会自动检测正确的宽度(4个项目)。但是,添加5个项目并不能检测到正确的宽度(假定宽度为3,但最终检测到宽度为2)

如何正确计算每组的宽度

以下是将项目填充到每个项目组的过程(删除一些不相关的内容):

程序TSplitForm.LoadScreen;
常数
框架宽度=170//每帧的宽度
框架高度=250//每帧的高度
帧_边距=30//每组右侧的边距
帧垂直计数=2//垂直堆叠的帧数
变量
CurGroup:TFlowPanel//当前正在填充的流面板
程序调整组(FP:TFlowPanel);
变量
Count,CountHalf,NewWidth,I:整数;
开始
//调整特定流面板的宽度以适合所有项目
计数:=FP.ComponentCount;
新宽度:=帧宽度+帧边距//如果没有项目,则为默认宽度
如果计数>0,则开始
//这就是我的计算不起作用的地方
CountHalf:=四舍五入(计数/帧垂直计数);
新宽度:=(CountHalf*帧宽度)+帧边距;
结束;
如果FP.Parent.Width NewWidth,则
FP.Parent.Width:=NewWidth;
//调整主流面板的宽度以适合所有包含的组面板
//(在滚动框内自动扩展以扩展滚动条)
计数:=TFlowPanel(FP.Parent.Parent).ControlCount;
新宽度:=0;
对于I:=0,计数-1开始
NewWidth:=NewWidth+FP.Parent.Parent.Controls[I].Width;
结束;
NewWidth:=NewWidth+边框_边距;
如果FP.Parent.Parent.Width NewWidth,则
FP.Parent.Parent.Width:=NewWidth;
结束;
程序添加(常量名称、标题、副标题:字符串);
变量
Frame:TfrmItemFrame;
开始
Frame:=AddItemFrame(CurGroup,Name)//创建面板,设置父级和名称
Frame.OnClick:=ItemClick;
Frame.Title:=标题;
Frame.Subtitle:=副标题;
ResizeGroup(CurGroup);
结束;
开始
CurGroup:=fpmain组;
添加('boxMainItem1','Item1','这是Item1');
添加('boxMainItem2','Item2','这是Item2');
添加('boxMainItem3','Item3','这是Item3');
添加('boxMainItem4','Item4','This is Item4');
添加('boxMainItem5','Item5','这是Item5');
CurGroup:=fpInventoryGroup;
添加('BoxInventionItem1','Item1','这是Item1');
添加('BoxInnovateM2','Item2','这是Item2');
添加('BoxInventionItem3','Item3','这是Item3');
添加('BoxInnovateM4','Item4','This is Item4');
添加('BoxInventionItem5','Item5','这是Item5');
添加('BoxInventionItem6','Item6','这是Item6');
添加('BoxInventionItem7','Item7','这是Item7');
结束;
这是该代码生成内容的屏幕截图:

如您所见,第一组有5项,隐藏了第5项,但第二组有7项,显示所有7项都很好

父/子关系的结构如下所示(流程面板以粗体显示):

  • 拆分形式:TSplitForm(主窗体)
    • ScrollBox 2:TScrollBox(主流程面板的容器)
      • fpMain:TFlowPanel(所有组面板的容器)
        • pMainGroup:TPanel(流面板和标题面板的容器)
          • fpMainGroup:TFlowPanel(项目框架的容器)
          • pMainGroupTitle:TPanel(组顶部的标题)
        • pInventoryGroup:TPanel(流程面板和标题面板的容器)
          • fpInventoryGroup:TFlowPanel(项目框架的容器)
          • PinVentoryGroup标题:TPanel(标题位于组顶部)
        • (更多组的其他面板)

我尝试使用每个flow面板的
AutoSize
属性,但它没有确认高度(向上2个),使事情变得更糟。基本上,我只需要正确地检测这些流面板中的总列数。

您不需要部分平铺,因此在计算需要多少列时,您需要最接近(等于或大于)的整数

在默认舍入模式下,
舍入(7/2)
为“4”。那很好。但是
Round(5/2)
是“2”

如果X正好是中间值,则使用默认舍入模式(rmNearest) 在两个整数之间,结果总是偶数


对于只有两行的情况,向上取整可以是一种解决方案(除法总是一个整数或正好位于两个整数之间的数字)。对于一般解决方案,最好使用
Ceil

您不需要部分平铺,因此在计算需要多少列时,您需要最接近(等于或大于)的整数

Round(Count / FRAME_VERT_COUNT);
在默认舍入模式下,
舍入(7/2)
为“4”。那很好。但是
Round(5/2)
是“2”

如果X正好是中间值,则使用默认舍入模式(rmNearest) 在两个整数之间,结果总是偶数

对于只有两行的情况,向上取整可以是一种解决方案(除法总是一个整数或正好位于两个整数之间的数字)。对于一般解决方案,最好使用
Ceil

Round(Count / FRAME_VERT_COUNT);
这里的
FRAME\u VERT\u COUNT
2
。当
Count
5
时,表达式变为

Rount(2.5);
默认舍入模式为四舍五入,计算结果为
2
。当
Count
7
时,表达式为

Round(3.5); 
四舍五入表示这是
4

你可以照Sertac的建议做
(Count + FRAME_VERT_COUNT - 1) div FRAME_VERT_COUNT