Исправление бага с заголовками столбцов в TListView в Delphi XE3
В данной статье мы рассмотрим проблему, связанную с потерей заголовка последнего столбца в компоненте TListView после его удаления, а также предложим решение этой проблемы.
Проблема
Пользователи, работающие с компонентом TListView в Delphi XE3, столкнулись с проблемой, когда после удаления столбца, заголовок последнего столбца терял свой текст. Это происходило независимо от того, какой столбец был удален, и не зависело от того, был ли удален первый, последний или любой другой столбец между ними. После удаления столбца, текст заголовка последнего столбца становился пустым.
Пример кода, вызывающего проблему
procedure TForm1.Button2Click(Sender: TObject);
begin
ListView1.Columns.Delete(1);
end;
Подтвержденное решение
Пользователи обнаружили, что проблема возникает в Delphi XE3, но не в более ранних версиях, таких как Delphi 2009 и XE2. Один из пользователей предложил решение, связанное с сохранением FOrderTag столбцов при их перемещении, что было предложено ранее для решения другой проблемы с порядком столбцов. Однако, после сохранения FOrderTag, удаление среднего столбца приводило к появлению "дыр" в последовательности, что не нравилось нативному контролу.
Для исправления этого бага был предложен следующий код:
destructor TListColumn.Destroy;
var
Columns: TListColumns;
i: Integer;
begin
Columns := TListColumns(Collection);
if TListColumns(Collection).Owner.HandleAllocated then
ListView_DeleteColumn(TListColumns(Collection).Owner.Handle, Index);
for i := 0 to Columns.Count - 1 do
if Columns[i].FOrderTag > FOrderTag then
Dec(Columns[i].FOrderTag);
inherited Destroy;
Columns.UpdateCols;
end;
Также было предложено удалять подстроки удаляемого столбца с помощью следующей утилиты:
procedure ListViewDeleteColumn(ListView: TListView; Col: Integer);
var
i: Integer;
ColumnOrder: array of Integer;
begin
SetLength(ColumnOrder, ListView.Columns.Count);
ListView_GetColumnOrderArray(
ListView.Handle, ListView.Columns.Count, PInteger(ColumnOrder));
Assert(ColumnOrder[Col] <> 0, 'column with items cannot be removed');
for i := 0 to ListView.Items.Count - 1 do
if Assigned(ListView.Items[i].SubItems) and
(ListView.Items[i].SubItems.Count >= Col) then
ListView.Items[i].SubItems.Delete(ColumnOrder[Col] - 1);
ListView.Columns.Delete(Col);
end;
Альтернативные решения
Пользователи также предложили альтернативные способы удаления столбцов, включая использование API-макроса ListView_DeleteColumn, но эти методы могли приводить к потере синхронизации с коллекцией столбцов и другим непредвиденным ошибкам.
Заключение
Для разработчиков, столкнувшихся с подобной проблемой, рекомендуется использовать предложенные решения, чтобы избежать потери заголовков столбцов в компоненте TListView. Важно понимать, что при удалении столбца необходимо также обрабатывать и подстроки, связанные с этим столбцом. Обратите внимание, что для полного решения проблемы может потребоваться дополнительная интеграция и исправления в VCL, которые могут быть выполнены разработчиками Embarcadero.
Примечание: В случае возникновения дополнительных проблем или вопросов, рекомендуется обратиться к официальной поддержке Embarcadero или рассмотреть возможность создания отчета о проблеме в их системе отслеживания ошибок.
Проблема в Delphi XE3 заключается в потере текста заголовка последнего столбца в компоненте TListView после его удаления.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.