将TCombobox列添加到Firemonkey TGrid [英] Add a TCombobox Column to a Firemonkey TGrid

查看:93
本文介绍了将TCombobox列添加到Firemonkey TGrid的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题似乎已被回答,可能是MonkeyStyler/Mike Sutton回答的,但是,由于我使用的是Delphi 10 Seattle,因此代码和指南不再起作用.专门

This question appears to have been answered already, possibly by MonkeyStyler/Mike Sutton, however, as I am using Delphi 10 Seattle, provided code and guides don't work anymore. Specifically

firemonkey网格基础

不起作用,因为ApplyStyling事件处理程序现在仅被调用一次(在创建列时)

doesn't work because the ApplyStyling event handler is only called once now (at column create)

我想将TCombobox或TComboboxEdit列添加到aTGrid.

I want to add a TCombobox or TComboboxEdit column to aTGrid.

type
  TComboColumn = Class(TColumn)
  protected
    function CreateCellControl: TStyledControl; override; // works!
  End;

...

Grid1.AddObject(TComboColumn.Create(Grid1)); 

...

    function TComboColumn.CreateCellControl: TStyledControl;
    begin
      Result := TComboBox.Create(Self);
      TComboBox(Result).Items.Add('A');
      TComboBox(Result).Items.Add('B');
      TComboBox(Result).Items.Add('C');
      TComboBox(Result).OnChange := DoTextChanged; // strange hooks
    end;

这会在网格中创建组合框列,但每一行都是相同组合框,我不知道如何添加适用于此的GetValue和SetValue方法.

This creates the combobox column in the grid, but it's the same combobox in every row, and I have no idea how to add the GetValue and SetValue methods applicable here.

推荐答案

您需要做很多事情.开始吧. 首先,您需要声明一些数据类型,该数据类型将存储您的ComboBox列的值.

You need to do quite much. Let's start. At first you need declare some data type that will store the values for your ComboBox column.

  TComboRecord = record
    FieldValues: array of string;
    ItemSelected: integer;
    function Selected: string;
  end;


...
{ TComboRecord }

function TComboRecord.Selected: string;
begin
  Result := FieldValues[ItemSelected];
end;

,并用一些数据填充TList<TComboRecord>.

var
  ComboData: TList<TComboRecord>;
procedure PopulateComboData(Rows: cardinal);

implementation

procedure PopulateComboData(Rows: cardinal);
var
  RowI: cardinal;
  i: cardinal;
  ComR: TComboRecord;
begin
  for RowI := 1 to Rows do
  begin
    Setlength(ComR.FieldValues, random(5) + 1);
    for i := 0 to length(ComR.FieldValues) - 1 do
      ComR.FieldValues[i] := inttostr(random(64000));
    ComR.ItemSelected := 0;
    ComboData.Add(ComR);
  end;
end;

initialization

ComboData := TList<TComboRecord>.Create;

finalization

ComboData.Free;

不需要创建一个TComboBox上升点,以便它可以存储和处理TComboRecord类型数据.

Than you need create a TComboBox ascendant so that it could store and manipulate the TComboRecord type data.

  TComboBoxCell = class(TComboBox)
  private
    FComboData: TComboRecord;
    procedure SetComboData(const Value: TComboRecord);
    function GetComboData: TComboRecord;
  protected
    procedure SetData(const Value: TValue); override;
  public
    property ComboData: TComboRecord read GetComboData write SetComboData;
  end;
...

{ TComboBoxCell }


function TComboBoxCell.GetComboData: TComboRecord;
begin
  FComboData.ItemSelected:=ItemIndex;
  result:=FComboData;
end;

procedure TComboBoxCell.SetComboData(const Value: TComboRecord);
var
  s: string;
begin
  FComboData := Value;
  Items.Clear;
  for s in Value.FieldValues do
    Items.Add(s);
  ItemIndex := Value.ItemSelected;
end;

procedure TComboBoxCell.SetData(const Value: TValue);
begin
  inherited;
  ComboData := Value.AsType<TComboRecord>
end;

比您需要继承新的类形式TColumn:

Than you need to inherit a new class form TColumn:

  TComboColumn = class(TColumn)
  protected
    procedure DoComboChanged(Sender: TObject);
    function Grid: TComboExtendedGrid; overload;
    function CreateCellControl: TStyledControl; override; 
  end;
...

{ TComboColumn }

function TComboColumn.CreateCellControl: TStyledControl;
begin
  Result := TComboBoxCell.Create(Self);
  TComboBoxCell(Result).OnChange := DoComboChanged;
end;

procedure TComboColumn.DoComboChanged(Sender: TObject);
var
  P: TPointF;
  LGrid: TComboExtendedGrid;
begin
  LGrid := Grid;
  if not Assigned(LGrid) then
    Exit;
  if FUpdateColumn then
    Exit;
  if FDisableChange then
    Exit;
  P := StringToPoint(TFmxObject(Sender).TagString);
  LGrid.SetValue(Trunc(P.X), Trunc(P.Y),
    TValue.From<TComboRecord>(TComboBoxCell(Sender).ComboData));
  if Assigned(LGrid.FOnEditingDone) then
    LGrid.FOnEditingDone(Grid, Trunc(P.X), Trunc(P.Y));
end;

function TComboColumn.Grid: TComboExtendedGrid;
var
  P: TFmxObject;
begin
  Result := nil;
  P := Parent;
  while Assigned(P) do
  begin
    if P is TCustomGrid then
    begin
      Result := TComboExtendedGrid(P);
      Exit;
    end;
    P := P.Parent;
  end;
end;

您看到,现在我们必须对TGrid类进行子类型化,还必须通过Grid函数获取其处理程序,并且需要访问protected FOnEditingDone变量

You see that now we have to subtype TGrid class as well as we have to get its handler by Grid function and need access to protected FOnEditingDone variable

  TComboExtendedGrid = class(TGrid)
  private
    FOnEditingDone: TOnEditingDone;
  protected
    procedure SetValue(Col, Row: integer; const Value: TValue); override;
  end;
{ TComboExtendedGrid }

procedure TComboExtendedGrid.SetValue(Col, Row: integer; const Value: TValue);
begin
  inherited;

end;

最后,我们需要在表单单元中设置必要的创建和事件处理机制.将列变量添加到from声明中.

Finally we need set the necessary creation and event handliing mechanism in our form unit. Add a column variable to the from declaration.

  protected
    CCColumn:TComboColumn;

填充ComboData并创建列:

populate the ComboData and create the column:

procedure TForm1.Button1Click(Sender: TObject);
begin
  PopulateComboData(Grid2.RowCount);
  CCColumn:=TComboColumn.Create(Grid2);
  CCColumn.Parent := Grid2;
  CCColumn.Header := 'CB';
end;

并处理事件:

procedure TForm1.Grid2GetValue(Sender: TObject; const Col, Row: Integer;
  var Value: TValue);
begin
  case Col of
     6{Combo Column Number}: Value:=TValue.From<TComboRecord>(ComboData[Row])
  end;
end;

procedure TForm1.Grid2SetValue(Sender: TObject; const Col, Row: Integer;
  const Value: TValue);
begin
  case Col of
      6{Combo Column Number}: ShowMessage(Value.AsType<TComboRecord>.Selected);
  end;
end;

不要忘记将更改(如果需要)传递到ComboData列表.当前的处理程序将不会为您执行此操作.我更喜欢在Grid2SetValue事件处理程序中创建它.

Do not forget to pass changes (if you need) to ComboData list. The current handlers will not do this for you. I prefer making this in Grid2SetValue event handler.

这篇关于将TCombobox列添加到Firemonkey TGrid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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