将TCombobox列添加到Firemonkey TGrid [英] Add a TCombobox Column to a 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
不起作用,因为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屋!