Как найти фактическую ширину компонента сетки с полосой прокрутки в Delphi - PullRequest
2 голосов
/ 11 ноября 2009

У меня есть компонент сетки (DBGrid), в котором много столбцов. Из-за большого количества столбцов была создана полоса прокрутки, и, таким образом, некоторая часть сетки остается скрытой. Мне нужно выяснить, какова реальная ширина DBGrid, включая часть, которая не отображается из-за полосы прокрутки. Но свойство Width дает только ширину самого компонента. У кого-нибудь есть идеи?

Ответы [ 4 ]

1 голос
/ 12 ноября 2009

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

Как вы можете заметить, метод CalcDrawInfo - это то, что вы ищете. Поскольку он защищен, вы можете использовать хелпер класса или обычный защищенный хак, чтобы получить его.

procedure TDbGridHelper.AutoSizeLastColumn;
var
  DrawInfo: TGridDrawInfo;
  ColNo: Integer;
begin
  ColNo := ColCount - 1;
  CalcDrawInfo(DrawInfo);
  if (DrawInfo.Horz.LastFullVisibleCell < ColNo - 1) then Exit;

  if (DrawInfo.Horz.LastFullVisibleCell < ColNo) then
    ColWidths[ColNo] := DrawInfo.Horz.GridBoundary - DrawInfo.Horz.FullVisBoundary
  else
    ColWidths[ColNo] := ColWidths[ColNo] + DrawInfo.Horz.GridExtent - DrawInfo.Horz.FullVisBoundary
end;
1 голос
/ 11 ноября 2009

TDBGrid имеет свойство Columns. Каждый из столбцов имеет свое собственное свойство Width. Таким образом, вы можете зациклить все столбцы и суммировать их ширину.

Как это:

function TotalColumnsWidth(var AGrid: TDBGrid);
var
  i: Integer;
begin
  Result := 0;
  for i := to AGrid.Columns.Count - 1 do
    Result := Result + AGrid.Columns[i].Width;
end;
0 голосов
/ 11 ноября 2009

Вот функции, которые мы использовали в прошлом. Он учитывает ширину данных на основе шрифта, а также компенсирует вертикальные линии, если они видны

function GridTextWidth(fntFont : TFont; const sString : OpenString) :
  integer;
var
  f: TForm;
begin
  try
    f:=TForm.Create(nil);
    f.Font:=fntFont;
    result:=f.canvas.textwidth(sstring);
  finally
    f.Free;
    end;
end;




function CalcGridWidth(dbg : TDBGrid { the grid to meaure }): integer; { the "exact" width }
const cMEASURE_CHAR   = '0';
      iEXTRA_COL_PIX  = 4;
      iINDICATOR_WIDE = 11;
var i, iColumns, iColWidth, iTitleWidth, iCharWidth : integer;
begin
  iColumns := 0;
  result   := GetSystemMetrics(SM_CXVSCROLL);

  iCharWidth := GridTextWidth(dbg.font,cMeasure_char);

  with dbg.dataSource.dataSet do begin
    DisableControls;
    for i := 0 to FieldCount - 1 do with Fields[i] do
      if visible then
      begin
        iColWidth := iCharWidth * DisplayWidth;
        if dgTitles in dbg.Options then begin
          ititlewidth:=GridTextWidth(dbg.titlefont,displaylabel);
          if iColWidth < iTitleWidth then
            iColWidth := iTitleWidth;
        end;
        inc(iColumns, 1);
        inc(result, iColWidth + iEXTRA_COL_PIX);
      end;
      EnableControls;
    end;

  if dgIndicator in dbg.Options then
  begin
    inc(iColumns, 1);
    inc(result, iINDICATOR_WIDE);
  end;
  if dgColLines in dbg.Options then
    inc(result, iColumns)
  else
    inc(result, 1);
end;
0 голосов
/ 11 ноября 2009

Я думаю, что нашел решение (хотя это кажется немного странным). Чтобы найти разницу между шириной столбца и реальной шириной DBgrid (то есть найти ширину пустого пространства, оставшегося после последнего столбца), нам нужно отслеживать, какой столбец теперь отображается слева (что является текущим столбцом это прокручивается до). Мы можем сделать это, используя событие OnDrawColumnCell, поскольку оно будет рисовать только те столбцы, которые прокручиваются сейчас. Затем нам нужно вычислить сумму ширин всех видимых столбцов и вычесть ее из ширины DBGrid. Постскриптум Извините за плохой английский

Ex код:

     For i:=0 to Last do
     if Vis[i] then
     Begin
      Sum:=Sum+DBG.Columns[i].Width;
      Inc(Cnt);
     End;

     if dgColLines in DBG.Options then
     Sum := Sum + Cnt;

  //add indicator column width
    if dgIndicator in DBG.Options then
    Sum := Sum + IndicatorWidth;
    Dif:=DBG.ClientWidth - Sum;
...