TStringGrid列调整大小事件?

时间:2015-02-15 23:00:44

标签: delphi tstringgrid

TStringGrid有一个TGridOption goColSizing,允许在拖动列之间的边距时在运行时自动调整列的大小。列大小发生时是否会触发相应的事件?如果列大小发生变化,我想调整另一个组件的大小以匹配某个列的大小/位置。

3 个答案:

答案 0 :(得分:3)

据我所知,没有任何事件可以通知您这样的修改。我认为您可以做的最好的事情是对控件进行子类化并覆盖ColWidthsChanged方法:

  

当列宽变化时响应。

     

在列宽更改后立即调用ColWidthsChanged。更改可以通过设置ColWidths属性,设置DefaultColWidth属性,移动其中一个列,或者使用鼠标调整列大小来实现。

由于对控件进行子类化操作是一项非常繁重的操作,因此对子类进行一次操作可能是谨慎的,并且为了表示事件而重写此方法。

答案 1 :(得分:2)

也许我的答案有点迟了但是我偶然发现了同样的问题,并且如果你不是TSlassGrid的子类,我找到了一个更简单的解决方案。 我的解决方案涉及在OnMouseUp事件中使用Rtti从TCustomGrid检索受保护字段FGridState的值。

请注意,我有自己的Rtti类,其中包含一些类函数,可以更轻松地在整个程序代码中使用Rtti。

class function TRttiUtils.GetClassField(aClass: TClass;
  aFieldName: String): TRttiField;
var
  Fields: TArray<TRttiField>;
  Field: TRttiField;
begin
  Result := nil;

  Fields := GetClassFields(aClass);

  For Field in Fields do
    If Field.Name = aFieldName
    then begin
      Result := Field;
      break;
    end;
end;

class function TRttiUtils.GetClassFields(aClass: TClass): TArray<TRttiField>;
var
  RttiContext: TRttiContext;
  RttiType: TRttiInstanceType;
  Fields: TArray<TRttiField>;
begin
  RttiContext := TRttiContext.Create;
  RttiType := RttiContext.GetType(aClass) as TRttiInstanceType;
  Fields := RttiType.GetFields;

  Result := Fields;
end;

这是我在stringMrid的OnMouseUp事件中使用的两个类函数。

procedure TFrameCurrency.sgCurrenciesMouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  R: TPoint;
  Row, Col: Integer;
  GridStateField: TRttiField;
  GridState: TGridState;
  ColSizing: Boolean;
begin
  inherited;

  If Button = mbLeft
  then begin
    //Determine row and column
    (Sender As TStringGrid).MouseToCell(X, Y, R.X, R.Y);
    Row := R.Y;
    Col := R.X;

    //Check if it is ColSizing
    ColSizing := False;

    GridStateField := TRttiUtils.GetClassField(TStringGrid, 'FGridState');
    If Assigned(GridStateField)
    then begin
      GridState := GridStateField.GetValue(sgCurrencies).AsType<TGridState>;
      If GridState = gsColSizing
      then begin
        //specific code comes here

        ColSizing := True;
      end;
    end;

    If Not ColSizing
    then begin
      //sorting logic comes here
    end;
  end;
end;

我认为这是一个比TStringGrid子类更简洁,更简单的解决方案。

答案 2 :(得分:2)

我找到了另一个更容易的解决方案,一个依赖于Delphi奇怪的解决方案:帮助函数获得私有访问权限。如果我们为TCustomerGrid定义帮助器类(我们必须'帮助'TCustomGrid而不是TStringGrid,因为那是私有字段的位置):

TCustomGridHelper = class helper for TCustomGrid
  function GetGridState : TGridState;
  function GetSizingIndex : Integer;
end;

function TCustomGridHelper.GetGridState: TGridState;
begin
  Result := Self.FGridState;
end;

function TCustomGridHelper.GetSizingIndex: Integer;
begin
  Result := Self.FSizingIndex;
end;

现在,我们只需要使用它:

procedure TSomeForm.ProductAllowedGridMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  col, row: Integer;
  grid: TStringGrid;
begin
  if Button = mbLeft then begin
    grid := TStringGrid(Sender);
    if grid.GetGridState = gsColSizing then begin
      // display column and new size
      Caption := IntToStr(grid.GetSizingIndex) + ': ' + IntToStr(grid.ColWidths[grid.GetSizingIndex]);
    end;
  end;
end;