Перейти к содержанию
Fire Monkey от А до Я
  • 0

Как сделать автоматическое изменение высоты TListBoxItem под содержимое текста?


rareMax

Вопрос

MRLmzu7.png

 

Как можно узнать, вмещается ли полностью текст в TListBoxItem? На скрине выше видно, что в выделенном TListBoxItem"э текст "ушел" вверх и вниз. Как можно изменить TListBoxItem.Height, что-бы в этот TListBoxItem полностью поместился текст? 

 

Спасибо.

Ссылка на комментарий

Рекомендуемые сообщения

  • 1
  • Администраторы

Ответ косвенно был дан в теме Автоматический переход на вторую строку TLabel

 

Поэтому на базе этого ответа его легко модифицировать для этой задачи. Идея простая в момент загрузки стиля и изменения размеров TListBoxItem, вычислять высоту занимаемого текста и на основании этих данных переопределять высоту итема.

 

Практика

1. Для определения размеров текст используем TTextLayout. Лучше создавать объект этого класса один раз. Поскольку в нашем случае он будет использоваться часто.

procedure TForm1.FormCreate(Sender: TObject);
begin
  // FTextLyout: TTextLayout - поле формы
  FTextLyout := TTextLayoutManager.DefaultTextLayout.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeAndNil(FTextLyout);
end; 

2. Пишем свой обработчик, который мы будем вызывать по достижению двух событий:

  1. Изменение размера TListBoxItem. В этом случае нужно перевычислить высоту итема.
  2. При загрузки нового стиля итема, нам нужно заново вычислить высоту итема. Поскольку стиль может содержать новые настройки отображения текста (шрифт, размер и тд.)

Я назвал это событие CalculateItemHeght:

procedure TForm1.CalculateItemHeight(Sender: TObject);
var
  ListItem: TListBoxItem;
begin
  if Sender is TListBoxItem then
  begin
    ListItem := Sender as TListBoxItem;
    FTextLyout.BeginUpdate;
    try
      // Инициализируем текстовый слой для корректного вычисления 
      // размеров отображаемого текста
      FTextLyout.Text := ListItem.Text;
      FTextLyout.MaxSize := TPointF.Create(ListItem.Width, 1000);
      FTextLyout.WordWrap := ListItem.WordWrap;
      FTextLyout.Font := ListItem.Font;
      FTextLyout.HorizontalAlign := ListItem.TextAlign;
      FTextLyout.VerticalAlign := ListItem.VertTextAlign;
    finally
      FTextLyout.EndUpdate;
    end;
    // Получаем высоту текста при текущих настройках итема
    ListItem.Height := FTextLyout.Height;
  end;
end;

Обратите внимание, что этот код работает для горизонтальной ориентации TListBoxItem и обычного TListBoxItem итема без картинок. Поэтому я для упрощения понимания кода, принимаю за ширину текста ширину самого итема. Но как вы понимаете, текст в итеме имеет еще свои отступы и может располагаться, например, справа от изображения. В этом случае этот в этот код нужно будет добавить определение текущих размеров стилевого объекта текста, отвечающего за вывод текста в TListBoxItem.

 

Но в вашем примере этого не нужно.

 

3. Вешаем наш обработчик на два события каждого итема TListBoxItem.OnResize и TListBoxItem.OnApplyStyleLookup.

 

Результат

post-1-0-64169500-1395743642.jpgpost-1-0-81891400-1395743642.jpg

 

Ссылка на комментарий
Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...