В Delphi и Lazarus (LCL) компонент TStringGrid предоставляет возможность отображения табличных данных. Одной из задач при работе с TStringGrid является определение количества видимых столбцов. Для этого существует свойство VisibleColCount, которое, однако, может работать не совсем интуитивно. В этой статье мы разберем, как работает функция TCustomGrid.GetVisibleColCount, лежащая в основе этого свойства, и предложим альтернативные подходы для более точного определения видимых столбцов.
Проблема: Неоднозначность VisibleColCount
Как показывает обсуждение на форуме, свойство VisibleColCount может вводить в заблуждение. Оно не всегда точно отражает количество столбцов, которые пользователь фактически видит на экране. Это связано с несколькими факторами:
Частично видимые столбцы:VisibleColCount может учитывать частично видимые столбцы, расположенные слева.
Свойство Visible столбцов: В Lazarus (LCL) столбцы могут быть скрыты с помощью свойства Visible. Однако, VisibleColCountигнорирует это свойство в Delphi, и, следовательно, считает невидимые столбцы.
Фиксированные столбцы: Фиксированные столбцы (свойство FixedCols) не учитываются в VisibleColCount.
function TCustomGrid.GetVisibleColCount: Integer;
begin
with FGCache do begin
Result := VisibleGrid.Right-VisibleGrid.Left;
if GridWidth<=ClientWidth then
inc(Result)
end;
end;
Здесь FGCache - это запись, содержащая TRect под названием VisibleGrid. VisibleGrid описывает область сетки, содержащую видимые (полностью или частично) столбцы, исключая фиксированные столбцы. Функция возвращает разницу между правой и левой границами VisibleGrid. Дополнительное inc(Result) добавляется, если ширина сетки меньше или равна ширине клиентской области, что учитывает возможность отображения всех столбцов одновременно.
Проблема с совместимостью Delphi и Lazarus (LCL)
Важно помнить, что VisibleColCount существует для совместимости с Delphi. Однако, Delphi не поддерживает коллекцию Columns, доступную в LCL. Поэтому, как было сказано выше, VisibleColCount игнорирует свойство Visible столбцов в Delphi, что может приводить к неверным результатам в Lazarus (LCL), где свойство Visible активно используется.
Альтернативные решения для определения видимых столбцов
Учитывая недостатки VisibleColCount, можно использовать альтернативные подходы для более точного определения количества видимых столбцов.
1. Определение количества полностью и частично видимых столбцов (с учетом Visible)
Предложенный на форуме код предоставляет функции для определения количества полностью и частично видимых столбцов с учетом свойства Visible:
type
TMyStringGrid = class(TStringGrid);
function GetPartiallyVisibleCols(AGrid: TStringGrid): Integer;
var
xLeft: Integer;
xRight: Integer;
c, c1, c2: Integer;
begin
if AGrid.FixedCols > 0 then
xLeft := AGrid.CellRect(AGrid.FixedCols-1, 0).Right
else
xLeft :=0;
xRight := AGrid.ClientRect.Right;
Result := 0;
with TMyStringGrid(AGrid) do
begin
c1 := GCache.VisibleGrid.Left;
c2 := GCache.VisibleGrid.Right;
end;
for c := c1 to c2 do begin
if (AGrid.Columns[c].Visible) then
begin
if AGrid.CellRect(c, 0).Left < xLeft then
inc(Result)
else
if AGrid.CellRect(c, 0).Right > xRight then
inc(Result);
end;
end;
end;
function GetFullyOrPartiallyVisibleCols(AGrid: TStringGrid): Integer;
var
i: Integer;
begin
Result := 0;
with TMyStringGrid(AGrid) do
begin
for i := GCache.VisibleGrid.Left to GCache.VisibleGrid.Right do
begin
if AGrid.Columns[i].Visible then
Inc(Result);
end;
end;
end;
function GetFullyVisibleCols(AGrid: TStringGrid): Integer;
begin
Result := GetFullyOrPartiallyVisibleCols(AGrid) - GetPartiallyVisibleCols(AGrid);
end;
Пояснения:
TMyStringGrid = class(TStringGrid); - используется для доступа к защищенному полю GCache.
GetPartiallyVisibleCols - определяет количество частично видимых столбцов, учитывая свойство Visible.
GetFullyOrPartiallyVisibleCols - определяет количество полностью или частично видимых столбцов, учитывая свойство Visible.
GetFullyVisibleCols - определяет количество полностью видимых столбцов, вычитая из общего количества частично видимые.
В циклах добавлена проверка if AGrid.Columns[c].Visible then для учета видимости столбцов.
2. Более простой подход (только для полностью видимых)
Если вам нужно только количество полностью видимых столбцов, можно использовать следующий подход:
function GetFullyVisibleColumnCount(AGrid: TStringGrid): Integer;
var
i: Integer;
Rect: TRect;
begin
Result := 0;
for i := AGrid.FixedCols to AGrid.ColCount - 1 do
begin
if AGrid.Columns[i].Visible then
begin
Rect := AGrid.CellRect(i, 0);
if (Rect.Left >= 0) and (Rect.Right <= AGrid.ClientWidth) then
Inc(Result);
end;
end;
end;
Этот код перебирает все столбцы (исключая фиксированные) и проверяет, находится ли ячейка столбца полностью в пределах видимой области сетки и является ли столбец видимым.
Свойство VisibleColCount компонента TStringGrid может давать неточные результаты при определении количества видимых столбцов, особенно в Lazarus (LCL) с учетом свойства Visible столбцов. Предложенные альтернативные решения позволяют более точно определить количество полностью или частично видимых столбцов, учитывая различные факторы, такие как фиксированные столбцы, свойство Visible и частичную видимость. Выбор конкретного подхода зависит от ваших потребностей и требований к точности определения количества видимых столбцов. При разработке кроссплатформенных приложений, использующих TStringGrid, важно учитывать различия в поведении VisibleColCount между Delphi и Lazarus (LCL).
Функция `TCustomGrid.GetVisibleColCount` в Delphi определяет количество видимых столбцов в компоненте `TStringGrid`, но может давать неточные результаты, особенно в Lazarus (LCL) с учетом свойства `Visible` столбцов, поэтому предложены альтернативные реш
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.