Проблема выделения в TListView с отключенным отображением и градиентным фоном в Delphi XE4
Разработчики, работающие с компонентом TListView в Delphi XE4, могут столкнуться с неприятной особенностью: при использовании стиля просмотра файлов (explorer style) и установке свойства HideSelection в значение true, выделение элемента списка не скрывается при переключении фокуса на другой контроль. Вместо этого, прямоугольник выделения остается на месте, не превращаясь в серый, как это обычно происходит при отсутствии фокуса у ListView.
Описание проблемы
Пользователи отмечают, что при клике на другой компонент, выделение в TListView не скрывается, что выглядит некорректно и раздражающе. Это поведение может быть связано с ошибкой в Delphi или же являться особенностью самого контрола ListView от Microsoft.
Возможные решения
В контексте обсуждения были предложены различные решения:
Использование события OnExit для сохранения выделения и сброса выделения на nil.
Восстановление выделения при получении фокуса с помощью события OnEnter.
Отключение свойства HideSelection, чтобы выделение превращалось в серый цвет при потере фокуса.
Использование свойства AutoFocus для более естественного поведения при перемещении мыши.
Переход на виртуальный режим ListView, что предполагает использование событий OnData для предоставления контента.
Подтвержденный ответ
Разработчик David Heffernan объяснил, что это поведение является особенностью подложенного контрола, а не ошибкой в Delphi. Единственный известный обходной путь, который он знает, заключается в использовании виртуального режима для ListView. Однако, существуют альтернативные решения, которые не требуют перехода на виртуальный режим:
Используйте событие OnExit для сохранения выделения, а затем сбросьте выделение в nil. При получении фокуса, восстановите выделение.
В событии OnMouseEnter сделайте ListView активным, чтобы он реагировал на перемещение мыши.
Пример кода на Object Pascal (Delphi) для сохранения и восстановления выделения:
Type
TForm1 = class(TForm)
...
private
FSelected: TListItem;
...
end;
procedure TForm1.ListView1Enter(Sender: TObject);
begin
if (ListView1.SelCount = 0) and Assigned(FSelected) then
ListView1.Selected := FSelected;
end;
procedure TForm1.ListView1Exit(Sender: TObject);
begin
FSelected := ListView1.Selected;
if Assigned(FSelected) then ListView1.Selected := Nil;
end;
procedure TForm1.ListView1MouseEnter(Sender: TObject);
begin
ListView1.SetFocus;
end;
Также было предложено просто отключить свойство HideSelection, чтобы выделение превращалось в серый цвет при потере фокуса, что является более простым решением, не требующим дополнительного кода для сохранения и восстановления выделения.
В заключение, разработчикам стоит выбрать подходящий для их задачи обходной путь, учитывая все "за" и "против" каждого из них.
Проблема в Delphi XE4 заключается в некорректном поведении выделения в компоненте TListView с отключенным отображением выделения и градиентным фоном, когда выделение не скрывается при переключении фокуса на другой компонент.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.