如何修改DBGrid中的所有者绘制异常? [英] How to fix owner draw anomaly in DBGrid?

查看:175
本文介绍了如何修改DBGrid中的所有者绘制异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

继续该项目开始于:



如何根据其内容自动调整/缩放DBGrid(或其他类似的)列宽?



我使用@alzaimar答案根据自己的内容宽度自动匹配列,但他向我展示了如何增加宽度,但不显示如何减少,所以我补充了如上所示的代码:

  procedure TRecordsBrowserFrameBase.JvDBGrid2DrawColumnCell(Sender:TObject; const Rect:TRect; DataCol:Integer; Column:TColumn; State:TGridDrawState); 
var
h,p,g,r,w,t:整数;
const
colSpc = 10;
begin
{ajusta as colunas de uma grade de acordo com oconteúdodascélulas}
h:= Column.DropDownRows;
p:=(发件人为TJvDBGrid).CurrentDrawRow;
g:= Column.Width;
r:=(发件人为TJvDBGrid).VisibleRowCount;
w:= colSpc +(发件人为TJvDBGrid).Canvas.TextExtent(Column.Field.DisplayText).cx;
t:= colSpc +(发件人为TJvDBGrid).Canvas.TextExtent(Column.Title.Caption).cx;
{$ WARNINGS OFF}
//如果需要,增加列宽度
if(w> g)然后Column.Width:= w;
if(g if(p< r)和(h //如果需要,减少列大小(第10行)
if(p = r)then
begin
h:= Column.DropDownRows;
g:= Column.Width;
if(h> t)和(h Column.DropDownRows:= 0;
结束
{$ WARNINGS ON}
end;

所以,现在当我用向下箭头键滚动时,所选行颜色并不总是正确的位置,你可以看到在这张照片:





我做错了什么?

解决方案

p>此解决方案使所有列根据其内容进行扩展或缩小,不用考虑是否需要滚动条,并修复所选的单元格绘图故障和记录指针故障。

  type 
TColumnAutoAdjust = record {保存负责设置网格中列宽的信息}
Field:String; {其中存储信息的字段名称}
注册:Boolean; {表示此列的大小是否已经注册}
更新:Boolean; {表示列的实际大小已更新}
LastWidth:Integer; {Width表示行列的记录的最终文本}
CurrWidth:Integer; {表示当前大小和列宽}
Reverter:Integer; {表示记录的最大宽度,但小于当前的}
滚动:整数; {表示一次宽度调整后滚动的数量}
RecNo:Integer; {表示哪个是表中的记录增加了colune的宽度}
end;

var {inside the forms private}
gdCols:数组的TColumnAutoAdjust; {vetor de ajuste de largura de cada coluna na grade de resultado}
RegisteredCols:Integer; {quantas colunasjáforam registradas no controle de ajuste}
gdVisibleRows:Integer; {quantas linhas de cadastrosestãovisíveisda grade de resultado}
gdVisibleCols:Integer; {quantas colunas de cadastrosestãovisíveisda grade de resultado}

{显示网格}
RegisteredCols:= ResultGrid.Columns.Count;
SetLength(gdCols,RegisteredCols);
{libera a lista}
ResultGrid.Align:= alClient;
for i:= 0 to RegisteredCols -1 do {inicializando a largura das colunas no tamanho dotítulode cada}
begin
gdCols [i] .Field:= ResultGrid.Columns [i] .FieldName;
ResultGrid.Columns [i] .Width:= ResultGrid.Canvas.TextExtent(ResultGrid.Columns [i] .Title.Caption).cx;
ResultGrid.Columns [i] .Alignment:= taLeftJustify;
ResultGrid.Columns [i] .Title.Alignment:= taLeftJustify;
结束
BrowserQuery.Open;
ResultGrid.Show;
for i:= 0 to gdVisibleRows do
begin
BrowserQuery.Next;
ResultGrid.Refresh;
结束
for i:= 0 to gdVisibleRows do
begin
BrowserQuery.Prior;
ResultGrid.Refresh;
结束
BrowserQuery.First;
ResultGrid.SetFocus;
end

{after dataset scroll}
procedure TRecordsBrowserFrameBase.BrowserQueryAfterScroll(DataSet:TDataSet);
var
i,TitleWidth:Integer;
mayAdjustAgain:Boolean; {}
begin
{ajusta as colunas da grade de resultado a cada movimento da tabela de resultado}
mayAdjustAgain:= False;
for i:= 0 to RegisteredCols -1 do
begin
如果不是gdCols [i]。更新然后
begin
ResultGrid.Columns [i] .Width: = gdCols [i] .CurrWidth;
gdCols [i] .Scrolls:= 0;
gdCols [i] .Updated:= True;
end
else
begin
Inc(gdCols [i] .Scrolls);
if(DataSet.RecNo> gdCols [i] .RecNo + gdVisibleRows)或(DataSet.RecNo< gdCols [i] .RecNo - gdVisibleRows)然后
begin
TitleWidth:= MaxColSpacing + ResultGrid.Canvas.TextExtent(ResultGrid.Columns [i] .Title.Caption).cx;
gdCols [i] .LastWidth:= gdCols [i] .CurrWidth;
gdCols [i] .CurrWidth:= IFX(gdCols [i] .Reverter> TitleWidth,gdCols [i] .Reverter,TitleWidth);
gdCols [i] .Reverter:= IFX(gdCols [i] .Reverter> TitleWidth,TitleWidth,0);
gdCols [i] .Updated:= False;
mayAdjustAgain:= True;
结束
结束
结束
如果mayAdjustAgain然后
begin
ResultGrid.Refresh;
BrowserQueryAfterScroll(DataSet);
结束
结束

{on draw column cell}

程序TRecordsBrowserFrameBase.GridColumnWidthAdjust(发件人:TObject; const Rect:TRect; DataCol:Integer; Column:TColumn; State:TGridDrawState);
var
ColWidth,TextWidth,TitleWidth:Integer;
begin
{ajusta acapitalizaçãodo texto dascélulas}
(发件人为TJvDBGrid).Canvas.Pen.Color:= clWhite;
(发件人为TJvDBGrid).Canvas.Rectangle(Rect);
(发件人为TJvDBGrid).Canvas.TextOut(Rect.Left + 2,Rect.Top + 2,NameCase(Column.Field.DisplayText));
{ajusta as colunas de uma grade de acordo com oconteúdodascélulas}
gdVisibleRows:=(发件人为TJvDBGrid).VisibleRowCount;
gdVisibleCols:=(发件人为TJvDBGrid).VisibleColCount;
TitleWidth:= MaxColSpacing +(发件人为TJvDBGrid).Canvas.TextExtent(Column.Title.Caption).cx;
TextWidth:= MaxColSpacing +(发件人为TJvDBGrid).Canvas.TextExtent(NameCase(Column.Field.DisplayText))。
ColWidth:= Column.Width;
{$ WARNINGS OFF}
if(TextWidth> gdCols [DataCol] .Reverter)和(TextWidth< ColWidth)然后gdCols [DataCol] .Reverter:= TextWidth;
if(TextWidth> ColWidth)then {texto dacélulaémais largo que a coluna}
begin
gdCols [DataCol] .Registered:= True;
gdCols [DataCol] .LastWidth:= ColWidth;
gdCols [DataCol] .CurrWidth:= TextWidth;
gdCols [DataCol] .Updated:= False;
gdCols [DataCol] .RecNo:= BrowserQuery.RecNo;
gdCols [DataCol] .Reverter:= TitleWidth;
退出;
结束
if(ColWidth< TitleWidth)then {texto dacélulaémenor que otítuloda coluna}
begin
gdCols [DataCol] .Registered:= True;
gdCols [DataCol] .LastWidth:= ColWidth;
gdCols [DataCol] .CurrWidth:= TitleWidth;
gdCols [DataCol] .Updated:= False;
gdCols [DataCol] .Reverter:= TitleWidth;
退出;
结束
{$ WARNINGS ON}
end;


Continuing with the project started in:

How to auto fit/scale DBGrid's (or other similar) columns widths according to its contents?

I used the @alzaimar answer to auto fit the columns according to their content width, but he showed me how to increase the width, but not how to decrease, so I complemented the code as shown above:

procedure TRecordsBrowserFrameBase.JvDBGrid2DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  h, p, g, r, w, t : Integer;
const
  colSpc = 10;
begin
{ ajusta as colunas de uma grade de acordo com o conteúdo das células }
  h := Column.DropDownRows;
  p := (Sender as TJvDBGrid).CurrentDrawRow;
  g := Column.Width;
  r := (Sender as TJvDBGrid).VisibleRowCount;
  w := colSpc + (Sender as TJvDBGrid).Canvas.TextExtent(Column.Field.DisplayText).cx;
  t := colSpc + (Sender as TJvDBGrid).Canvas.TextExtent(Column.Title.Caption).cx;
{$WARNINGS OFF}
  // increase column width if needed
  if (w > g) then Column.Width := w;
  if (g < t) then Column.Width := t;
  if (p < r) and (h < w) then Column.DropDownRows := w;
  // decrease column size if needed (10th line)
  if (p = r) then
  begin
    h := Column.DropDownRows;
    g := Column.Width;
    if (h > t) and (h < g) then Column.Width := Column.DropDownRows;
    Column.DropDownRows := 0;
  end;
{$WARNINGS ON}
end;

So, now when I scroll with the down arrow key, the selected row color does not always is in the correct position as you can see in this picture:

What I am doing wrong?

解决方案

This solution makes all columns expand or shrink according to it's contents, without care if there has to be scroll bars or not, and fix the selected cell drawing malfunction and the the record pointer malfunction.

type
  TColumnAutoAdjust = record {Save the information responsible for setting column widths in the grid}
    Field: String;           {Field name whose information is being stored}
    Registered: Boolean;     {Indicates whether the size of this column already registered}
    Updated: Boolean;        {Indicates the actual size of the column was updated}
    LastWidth: Integer;      {Width indicates the final text of a record of a row column}
    CurrWidth: Integer;      {Indicates the current size and column width}
    Reverter: Integer;       {Indicates the greatest width recorded but that is less than the current}
    Scrolls: Integer;        {Indicates the amount of scrolls present after one width adjustment}
    RecNo: Integer;          {Indicates which was the record in the table which increased the width of colune}
  end;

var { inside the forms private }
  gdCols: array of TColumnAutoAdjust; { vetor de ajuste de largura de cada coluna na grade de resultado }
  RegisteredCols: Integer; { quantas colunas já foram registradas no controle de ajuste }
  gdVisibleRows: Integer; { quantas linhas de cadastros estão visíveis da grade de resultado }
  gdVisibleCols: Integer; { quantas colunas de cadastros estão visíveis da grade de resultado }

{ before showing the grid }  
    RegisteredCols := ResultGrid.Columns.Count;
    SetLength(gdCols, RegisteredCols); { determina o tamanho da vetor de controle de colunas }
    { libera a lista }
    ResultGrid.Align := alClient;
    for i := 0 to RegisteredCols -1 do { inicializando a largura das colunas no tamanho do título de cada }
    begin
      gdCols[i].Field := ResultGrid.Columns[i].FieldName;
      ResultGrid.Columns[i].Width := ResultGrid.Canvas.TextExtent(ResultGrid.Columns[i].Title.Caption).cx;
      ResultGrid.Columns[i].Alignment := taLeftJustify;
      ResultGrid.Columns[i].Title.Alignment := taLeftJustify;
    end;
    BrowserQuery.Open;
    ResultGrid.Show;
    for i := 0 to gdVisibleRows do
    begin
      BrowserQuery.Next;
      ResultGrid.Refresh;
    end;
    for i := 0 to gdVisibleRows do
    begin
      BrowserQuery.Prior;
      ResultGrid.Refresh;
    end;
    BrowserQuery.First;
    ResultGrid.SetFocus;
  end

{ after dataset scroll}      
procedure TRecordsBrowserFrameBase.BrowserQueryAfterScroll(DataSet: TDataSet);
var
  i, TitleWidth: Integer;
  mayAdjustAgain: Boolean; {  }
begin
{ ajusta as colunas da grade de resultado a cada movimento da tabela de resultado }
  mayAdjustAgain := False;
  for i := 0 to RegisteredCols -1 do
  begin
    if not gdCols[i].Updated then
    begin
      ResultGrid.Columns[i].Width := gdCols[i].CurrWidth;
      gdCols[i].Scrolls := 0;
      gdCols[i].Updated := True;
    end
    else
    begin
      Inc(gdCols[i].Scrolls);
      if (DataSet.RecNo > gdCols[i].RecNo + gdVisibleRows) or (DataSet.RecNo < gdCols[i].RecNo - gdVisibleRows) then
      begin
        TitleWidth := MaxColSpacing + ResultGrid.Canvas.TextExtent(ResultGrid.Columns[i].Title.Caption).cx;
        gdCols[i].LastWidth := gdCols[i].CurrWidth;
        gdCols[i].CurrWidth := IFX(gdCols[i].Reverter > TitleWidth, gdCols[i].Reverter, TitleWidth);
        gdCols[i].Reverter := IFX(gdCols[i].Reverter > TitleWidth, TitleWidth, 0);
        gdCols[i].Updated := False;
        mayAdjustAgain := True;
      end;
    end;
  end;
  if mayAdjustAgain then
  begin
    ResultGrid.Refresh;
    BrowserQueryAfterScroll(DataSet);
  end;
end;

{ on draw column cell }

procedure TRecordsBrowserFrameBase.GridColumnWidthAdjust(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  ColWidth, TextWidth, TitleWidth: Integer;
begin
{ ajusta a capitalização do texto das células }
  (Sender as TJvDBGrid).Canvas.Pen.Color := clWhite;
  (Sender as TJvDBGrid).Canvas.Rectangle(Rect);
  (Sender as TJvDBGrid).Canvas.TextOut(Rect.Left+2, Rect.Top+2, NameCase(Column.Field.DisplayText));
{ ajusta as colunas de uma grade de acordo com o conteúdo das células }
  gdVisibleRows := (Sender as TJvDBGrid).VisibleRowCount;
  gdVisibleCols := (Sender as TJvDBGrid).VisibleColCount;
  TitleWidth := MaxColSpacing + (Sender as TJvDBGrid).Canvas.TextExtent(Column.Title.Caption).cx;
  TextWidth := MaxColSpacing + (Sender as TJvDBGrid).Canvas.TextExtent(NameCase(Column.Field.DisplayText)).cx;
  ColWidth := Column.Width;
  {$WARNINGS OFF}
  if (TextWidth > gdCols[DataCol].Reverter) and (TextWidth < ColWidth) then gdCols[DataCol].Reverter := TextWidth;
  if (TextWidth > ColWidth) then { texto da célula é mais largo que a coluna }
  begin
    gdCols[DataCol].Registered := True;
    gdCols[DataCol].LastWidth := ColWidth;
    gdCols[DataCol].CurrWidth := TextWidth;
    gdCols[DataCol].Updated := False;
    gdCols[DataCol].RecNo := BrowserQuery.RecNo;
    gdCols[DataCol].Reverter := TitleWidth;
    Exit;
  end;
  if (ColWidth < TitleWidth) then { texto da célula é menor que o título da coluna }
  begin
    gdCols[DataCol].Registered := True;
    gdCols[DataCol].LastWidth := ColWidth;
    gdCols[DataCol].CurrWidth := TitleWidth;
    gdCols[DataCol].Updated := False;
    gdCols[DataCol].Reverter := TitleWidth;
    Exit;
  end;
{$WARNINGS ON}
end;

这篇关于如何修改DBGrid中的所有者绘制异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆