Hide empty space behind invisible list box items

人盡茶涼 提交于 2019-12-13 02:39:36

问题


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:

  1. Set the TListBox.ItemHeight property back to 0
  2. Set the TListBoxItem.Height property of each item to desired height
  3. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!