Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 将TCombobox列添加到Firemonkey TGrid_Delphi_Firemonkey - Fatal编程技术网

Delphi 将TCombobox列添加到Firemonkey TGrid

Delphi 将TCombobox列添加到Firemonkey TGrid,delphi,firemonkey,Delphi,Firemonkey,这个问题似乎已经得到了回答,可能是MonkeyStyler/Mike Sutton回答的,但是,当我使用Delphi 10西雅图时,如果代码和指南不再起作用了。具体地 无法工作,因为ApplySyling事件处理程序现在只调用一次(在列创建时) 我想在aTGrid中添加一个TComboxBox或TComboxEdit列 type TComboColumn = Class(TColumn) protected function CreateCellControl: TStyled

这个问题似乎已经得到了回答,可能是MonkeyStyler/Mike Sutton回答的,但是,当我使用Delphi 10西雅图时,如果代码和指南不再起作用了。具体地

无法工作,因为ApplySyling事件处理程序现在只调用一次(在列创建时)

我想在aTGrid中添加一个TComboxBox或TComboxEdit列

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


这将在网格中创建combobox列,但每行都是相同的combobox,我不知道如何添加适用于此处的GetValue和SetValue方法。

您需要做很多工作。让我们开始吧。 首先,您需要声明一些数据类型来存储
组合框
列的值

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


...
{ TComboRecord }

function TComboRecord.Selected: string;
begin
  Result := FieldValues[ItemSelected];
end;
并用一些数据填充
TList

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;
然后您需要继承一个新的类表单
t列

  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;
最后,我们需要在表单单元中设置必要的创建和事件处理机制。将列变量添加到from声明中

  protected
    CCColumn:TComboColumn;
填充ComboData并创建列:

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;
过程TForm1.Grid2GetValue(发送方:TObject;常量列,行:Integer;
var值:TValue);
开始
案例
6{Combo Column Number}:Value:=TValue.From(ComboData[Row])
结束;
结束;
过程TForm1.Grid2SetValue(发送方:ToObject;常量列,行:整数;
常量值:TValue);
开始
案例
6{Combo Column Number}:ShowMessage(Value.AsType.Selected);
结束;
结束;

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

以下是将组合框添加到FMX TGrid的简单方法。诚然,这个解决方案在每个组合中都有相同的项,但这就是我现在所能实现的

type
  TComboColumn = class(TPopupColumn)
    function CreateCellControl: TStyledControl; override;
  end;

。。。只是为了延续

procedure TfrmMain.FormCreate(Sender: TObject);
begin
   AGrid := TComboExtendedGrid.Create(Self);
   AGrid.Parent := Self;
   AGrid.Align := TAlignLayout.Client;
   AGrid.Options := AGrid.Options + [TGridOption.AlwaysShowEditor];
   AGrid.OnGetValue := AGridGetValue;
   AGrid.OnSetValue := AGridSetValue;
   AGrid.RowCount := 5;

   ComboData := TList<TComboRecord>.Create;
   PopulateComboData(AGrid.RowCount);

   CCColumn := TComboColumn.Create(AGrid);
   CCColumn.Parent := AGrid;
   CCColumn.Header := 'Combohere';   
end;
过程TfrmMain.FormCreate(发送方:TObject);
开始
AGrid:=tcombodedGrid.Create(Self);
AGrid.Parent:=Self;
AGrid.Align:=TAlignLayout.Client;
AGrid.Options:=AGrid.Options+[TGridOption.AlwaysShowEditor];
AGrid.OnGetValue:=AGridGetValue;
AGrid.OnSetValue:=AGridSetValue;
AGrid.RowCount:=5;
ComboData:=TList.Create;
PopulateComboData(AGrid.RowCount);
CCColumn:=TComboColumn.Create(AGrid);
CCColumn.Parent:=AGrid;
CCColumn.Header:='Combohere';
结束;

这看起来非常有前途和全面(远远超过我的写作能力,但我可读)。当我有机会彻底测试它时,我会接受这个答案。谢谢让我们直说吧。我现在把它都整理好了。对于D10,我改变了两件事。1. <代码>StringToPoint现在位于
FMX.Utils
2<代码>s:=Value.AsType.SelectedGrid1中的code>SetValue导致D10中出现AV。我已将其替换为
ComR:=Value.AsType;如果ComR.ItemSelected>-1,则s:=ComR.FieldValues[ComR.ItemSelected]用于D10。然后就可以了,我还加了3<代码>类型TComboColumn=class(TColumn)私有FUpdateColumn:布尔值;FDisableChange:布尔值
与我首先使用的XE7版本相比。@nolaspeaker您可以尝试编写
ApplyStyle
ApplyStyling
过程来设置单元格控件的显示(字体颜色、字体大小等)。使用
TComboRecord
作为容器传递必要的标志非常方便。我没有使用
ApplyStyle
Applystyling
的经验,但更重要的是,我的下一个问题是关于网格显示的。组合框的当前选定值仅在实际选定单元格时显示,否则单元格仅显示(记录)。这是一个很长的答案吗?
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;
type
  TComboColumn = class(TPopupColumn)
    function CreateCellControl: TStyledControl; override;
  end;
function TComboColumn.CreateCellControl: TStyledControl;
var
  ComR: TComboRecord;
  i: Integer;
begin
   Result := TComboBoxCell.Create(self);
   // now they all have the same drop-down values
   ComR := frmMain.ComboData[0];
   for i := 0 to Length(ComR.FieldValues) do
     TComboBoxCell(Result).Items.Add(ComR.FieldValues[i]);
end
procedure TfrmMain.FormCreate(Sender: TObject);
begin
   AGrid := TComboExtendedGrid.Create(Self);
   AGrid.Parent := Self;
   AGrid.Align := TAlignLayout.Client;
   AGrid.Options := AGrid.Options + [TGridOption.AlwaysShowEditor];
   AGrid.OnGetValue := AGridGetValue;
   AGrid.OnSetValue := AGridSetValue;
   AGrid.RowCount := 5;

   ComboData := TList<TComboRecord>.Create;
   PopulateComboData(AGrid.RowCount);

   CCColumn := TComboColumn.Create(AGrid);
   CCColumn.Parent := AGrid;
   CCColumn.Header := 'Combohere';   
end;