问题
I can see other people have had this issue, and the proposed solution is not working for me.
I have a list box with a number of static items populated in design-time, and in run-time, some list box items have their visibility changed. However, those items which are not visible leave an empty space in the list box where that item belongs. It's proposed to set the invisible item height to 0, and it's apparently worked for people, but it's not working for me.
This is a common function I wrote to accommodate for this:
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;
While stepping through the code, I can confirm that after I.Height:= 0;
the Height
is in fact 0. However, the problem still persists, and there's still an empty void in the list box, as if the list box control ignores what height I set the item.
How can I make invisible items truly hidden from the list box including this empty space behind it, without deleting these items? My app has many different list box controls with the same issue, so a global solution would be ideal.
NOTE: This is using Windows 32 as a platform.
EDIT
I did a few more trials, and discovered something. In design-time, the list box items Height
property defaults to the parent list box's ItemHeight
property. If I change the Height
of a specific item in design-time, it immediately reverts back to what it was before. So the question then becomes... why is Firemonkey reverting TListBoxItem.Height
every time I change it?
回答1:
Thanks to some troubleshooting help from Tom in the comments, I've discovered what was going wrong and how to get around it.
The root of the issue was the fact that my TListBox
controls were given a custom value for ItemHeight
although by default they have 0
. When ItemHeight
is 0
, you're allowed to set the height of individual items. However when ItemHeight
is anything else, the list box control takes over and forcefully sets all items to that height, regardless of what you assign to each item.
So the steps to fix this were:
- Set the
TListBox.ItemHeight
property back to0
- Set the
TListBoxItem.Height
property of each item to desired height - Modify my procedure to set to desired height rather than
TListBox.ItemHeight
And the procedure now looks like this:
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;
This is still a rather messy fix to the original underlying issue, but it does solve the problem.
If for any reason you want to be able to have list items of varying height, you can do so by storing the desired height in the Tag
property of each list box item (although Tag
is a NativeInt
and Height
is Extended
so accuracy would be lost) ...
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;
来源:https://stackoverflow.com/questions/29436085/hide-empty-space-behind-invisible-list-box-items