DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: tigerleentu
今日帖子: 10
在线用户: 17
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 zcbly (小菜) ▲▲▲▲△ -
普通会员
2019/5/15 10:20:04
标题:
求助:Add a TCombobox Column to a Firemonkey TGrid 浏览:1280
加入我的收藏
楼主: 按照下面链接抄的代码:
https://stackoverflow.com/questions/32920219/add-a-tcombobox-column-to-a-firemonkey-tgrid/32922571#32922571
没有出现效果,请大神帮忙!代码见附件!
此帖子包含附件:zcbly_2019515102259.rar 大小:75.7K
----------------------------------------------
-
作者:
男 zcbly (小菜) ▲▲▲▲△ -
普通会员
2019/5/15 11:06:48
1楼: 顶起来,不要沉底了。
----------------------------------------------
-
作者:
男 zcbly (小菜) ▲▲▲▲△ -
普通会员
2019/5/15 16:15:26
2楼: // 出处https://stackoverflow.com/questions/32920219/add-a-tcombobox-column-to-a-firemonkey-tgrid/32922571#32922571


unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes,
  System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Rtti,
  FMX.Grid.Style, FMX.Controls.Presentation, FMX.ScrollBox, FMX.Grid,
  Generics.Collections,
  FMX.ListBox, FMX.StdCtrls, FMX.Utils;

type

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

  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;

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

  TComboColumn = class(TColumn)
  private
    FUpdateColumn: Boolean;
    FDisableChange: Boolean;
  protected
    procedure DoComboChanged(Sender: TObject);
    function Grid: TComboExtendedGrid; overload;
    function CreateCellControl: TStyledControl;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Grid2: TGrid;

    procedure Grid2GetValue(Sender: TObject; const Col, Row: integer;
      var Value: TValue);
    procedure Grid2SetValue(Sender: TObject; const Col, Row: integer;
      const Value: TValue);
    procedure Button1Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
    AGrid: TComboExtendedGrid;
  protected
    CCColumn: TComboColumn;
  end;

var

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

implementation

{$R *.fmx}

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

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;

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;

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;

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

end;

procedure TForm1.Button1Click(Sender: TObject);

begin
  PopulateComboData(StringGrid1.RowCount);
  CCColumn := TComboColumn.Create(StringGrid1);
  CCColumn.Parent := StringGrid1;
  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;

initialization

ComboData := TList<TComboRecord>.Create;

finalization

ComboData.Free;

end.
----------------------------------------------
-
作者:
男 zcbly (小菜) ▲▲▲▲△ -
普通会员
2019/5/15 16:19:01
3楼: 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.


This looks very promising and comprehensive (way above my ability to write, but readable to me). Will accept as answer when I've had a chance to test it thoroughly. Thanks! – nolaspeaker Oct 4 '15 at 18:34 
Let's get this straight. I got it all sorted now. There are 2 things I changed for D10. 1. StringToPoint is now in FMX.Utils 2. s := Value.AsType<TComboRecord>.Selected; in Grid1.SetValue causes an AV in D10. I have replaced that with ComR := Value.AsType<TComboRecord>; if ComR.ItemSelected > -1 then s := ComR.FieldValues[ComR.ItemSelected]; for D10. Then it works just fine. – nolaspeaker Oct 11 '15 at 18:20 
I also added 3. type TComboColumn = class(TColumn) private FUpdateColumn: Boolean; FDisableChange: Boolean; as compared to the XE7 version that I got working first. – nolaspeaker Oct 11 '15 at 18:38 
@nolaspeaker You can try to write ApplyStyle and ApplyStyling procedures for setting the presentation (font color, font size etc.) of the cell controls as well. It is very comfortable to pass necessary flags using TComboRecord as a container. – asd-tm Oct 11 '15 at 18:51
1
I have no experience with ApplyStyle and Applystyling, but more importantly, my next question is about the grid display. The currently selected value of the combobox is only shown when the cell is actually selected, otherwise the cell just shows (record). Is that a long answer? – nolaspeaker Oct 11 '15 at 18:55
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行136.7188毫秒 RSS