隐藏空 space 在不可见的列表框项目后面
Hide empty space behind invisible list box items
我可以看到 other people have had this issue,建议的解决方案对我不起作用。
我有一个列表框,其中包含许多在设计时填充的静态项,而在 运行 时,一些列表框项的可见性发生了变化。但是,那些不可见的项目会在该项目所属的列表框中留下一个空的 space。建议将不可见项目高度设置为0,这显然对人们有用,但对我不起作用。
这是我为此编写的一个常用函数:
procedure FixHidden(AListBox: TListBox);
var
X: Integer;
I: TListBoxItem;
begin
for X := 0 to AListBox.Count-1 do begin
I:= AListBox.ItemByIndex(X);
if I.Visible then
I.Height:= AListBox.ItemHeight
else
I.Height:= 0;
end;
end;
在单步执行代码时,我可以确认在 I.Height:= 0;
之后 Height
实际上是 0。但是,问题仍然存在,列表框中仍然有一个空白,好像列表框控件忽略了我设置的项目的高度。
如何使不可见的项目真正从列表框中隐藏起来,包括它后面的空 space,而不删除这些项目?我的应用程序有许多具有相同问题的不同列表框控件,因此一个全局解决方案将是理想的。
注意:这是使用 Windows 32 作为平台。
编辑
我又做了几次试验,发现了一些东西。在设计时,列表框项目 Height
属性 默认为父列表框的 ItemHeight
属性。如果我在设计时更改特定项目的 Height
,它会立即恢复到原来的状态。所以问题就变成了......为什么每次我更改 Firemonkey 时都会恢复 TListBoxItem.Height
?
感谢 Tom 在评论中提供的一些故障排除帮助,我发现了问题所在以及解决方法。
问题的根源在于我的 TListBox
控件被赋予了 ItemHeight
的自定义值,尽管默认情况下它们具有 0
。当 ItemHeight
为 0
时,您可以设置单个项目的高度。但是,当 ItemHeight
为其他任何内容时,列表框控件会接管并强制将所有项目设置为该高度,而不管您为每个项目分配什么。
所以解决这个问题的步骤是:
- 将
TListBox.ItemHeight
属性 设置回 0
- 将每个项目的
TListBoxItem.Height
属性 设置为所需的高度
- 修改我的程序以设置所需的高度而不是
TListBox.ItemHeight
程序现在看起来像这样:
procedure FixHidden(AListBox: TListBox; AHeight: Extended = 32.0);
var
X: Integer;
I: TListBoxItem;
begin
for X := 0 to AListBox.Count-1 do begin
I:= AListBox.ItemByIndex(X);
if I.Visible then
I.Height:= AHeight
else
I.Height:= 0;
end;
end;
这仍然是对原始潜在问题的一个相当混乱的修复,但它确实解决了问题。
如果出于任何原因您希望能够拥有不同高度的列表项,您可以通过将所需高度存储在每个列表框项的 Tag
属性 中来实现(尽管Tag
是 NativeInt
而 Height
是 Extended
所以准确性会丢失) ...
procedure FixHidden(AListBox: TListBox);
var
X: Integer;
I: TListBoxItem;
begin
for X := 0 to AListBox.Count-1 do begin
I:= AListBox.ItemByIndex(X);
if I.Visible then
I.Height:= I.Tag
else
I.Height:= 0;
end;
end;
我可以看到 other people have had this issue,建议的解决方案对我不起作用。
我有一个列表框,其中包含许多在设计时填充的静态项,而在 运行 时,一些列表框项的可见性发生了变化。但是,那些不可见的项目会在该项目所属的列表框中留下一个空的 space。建议将不可见项目高度设置为0,这显然对人们有用,但对我不起作用。
这是我为此编写的一个常用函数:
procedure FixHidden(AListBox: TListBox);
var
X: Integer;
I: TListBoxItem;
begin
for X := 0 to AListBox.Count-1 do begin
I:= AListBox.ItemByIndex(X);
if I.Visible then
I.Height:= AListBox.ItemHeight
else
I.Height:= 0;
end;
end;
在单步执行代码时,我可以确认在 I.Height:= 0;
之后 Height
实际上是 0。但是,问题仍然存在,列表框中仍然有一个空白,好像列表框控件忽略了我设置的项目的高度。
如何使不可见的项目真正从列表框中隐藏起来,包括它后面的空 space,而不删除这些项目?我的应用程序有许多具有相同问题的不同列表框控件,因此一个全局解决方案将是理想的。
注意:这是使用 Windows 32 作为平台。
编辑
我又做了几次试验,发现了一些东西。在设计时,列表框项目 Height
属性 默认为父列表框的 ItemHeight
属性。如果我在设计时更改特定项目的 Height
,它会立即恢复到原来的状态。所以问题就变成了......为什么每次我更改 Firemonkey 时都会恢复 TListBoxItem.Height
?
感谢 Tom 在评论中提供的一些故障排除帮助,我发现了问题所在以及解决方法。
问题的根源在于我的 TListBox
控件被赋予了 ItemHeight
的自定义值,尽管默认情况下它们具有 0
。当 ItemHeight
为 0
时,您可以设置单个项目的高度。但是,当 ItemHeight
为其他任何内容时,列表框控件会接管并强制将所有项目设置为该高度,而不管您为每个项目分配什么。
所以解决这个问题的步骤是:
- 将
TListBox.ItemHeight
属性 设置回0
- 将每个项目的
TListBoxItem.Height
属性 设置为所需的高度 - 修改我的程序以设置所需的高度而不是
TListBox.ItemHeight
程序现在看起来像这样:
procedure FixHidden(AListBox: TListBox; AHeight: Extended = 32.0);
var
X: Integer;
I: TListBoxItem;
begin
for X := 0 to AListBox.Count-1 do begin
I:= AListBox.ItemByIndex(X);
if I.Visible then
I.Height:= AHeight
else
I.Height:= 0;
end;
end;
这仍然是对原始潜在问题的一个相当混乱的修复,但它确实解决了问题。
如果出于任何原因您希望能够拥有不同高度的列表项,您可以通过将所需高度存储在每个列表框项的 Tag
属性 中来实现(尽管Tag
是 NativeInt
而 Height
是 Extended
所以准确性会丢失) ...
procedure FixHidden(AListBox: TListBox);
var
X: Integer;
I: TListBoxItem;
begin
for X := 0 to AListBox.Count-1 do begin
I:= AListBox.ItemByIndex(X);
if I.Visible then
I.Height:= I.Tag
else
I.Height:= 0;
end;
end;