Delphi CxGrid 汇总(2) 转

17. 怎样设计多表头的cxGrid?
解决:cxGrid可以解决如下的表头:
---------------------------------
| 说明1 | 说明2 |
---------------------------------
| 字段1 | 字段2 | 字段3 | 字段4 |
| 字段5 | 字段6 |
| 字段7 | 字段8 | 字段9 |
实现这个很简单,你可以直接在上面拖动字段名,拖动时会显示箭头的,放入你想显示的位置就OK了。或者在鼠标右击cxGrid1DBBandedTableView1菜单里的Edit Layout里也可以拖放。

但是cxGrid不能实现如下的多表头形式:
---------------------------------
| 说明1 | 说明2 |
---------------------------------
| 说明3 | 说明4 | 说明5 | 说明6 |
| 字段1 | 字段2 |
| 字段3 | 字段4 | 字段5 |
不知道有谁能实现这样的多表头?

****************************************************************************
18. 在主从表结构时,当点开“+”时怎样将焦点聚在相应主表的记录上?
解决:
var
HitTest: TcxCustomGridHitTest;

procedure TColumnsShareDemoMainForm.tvProjectsMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
// Note that the Sender parameter is a Site
  HitTest := (Sender as TcxGridSite).GridView.ViewInfo.GetHitTest(X, Y);
// The point belongs to the [+]/[-] button area
  if HitTest is TcxGridExpandButtonHitTest then
// Move focus to the record
  TcxGridExpandButtonHitTest(HitTest).GridRecord.Focused := True;
end;

****************************************************************************
19 CXGrid4如何展开全部节点
解决:GridDBTableView1.DataController.Groups.FullExpand;

****************************************************************************
20. cxGrid如何动态创建Items的Editor的项?
解决:cxGrid的列有一个属性,它的编辑框可以指定combobox,spinedit等.在设计时,可以为
combobox的items添加项目.请问是否可以动态创建?(run-time时由程序加入)

  1. var  
  2. A:TDataSource:  
  3. B:TcxlookupcomboboxProperties;  
  4. begin  
  5. A:=TDataSource.create(self);  
  6. B:=tcxlookupcomboboxproperties.create(self);  
  7. A.Dataset:=Dic_ry_xb;//此处指定数据源。  
  8. b.listdource:=a;//此处指明字段的listsource属性。  
  9. b.keyfieldnames:='a'//此处指明字段的关键字段  
  10. b.listfieldnames:='b'//此处指明字段的返回值。  
  11. b.listcolumns.items[0].caption:='x; //此处默认是会建立一个字段,但是显示的表头是name,所以此处让它显示为自己想要的中午显示。  
  12. cxGrid1DBTableView1c1_sex_code.Properties:=b; //此处指明是那个字段。  
  13. end//这个是初始化的代码  

****************************************************************************
21. 拷贝文件时有进度显示
解决:

  1. procedure TForm1.mycopyfile(sourcef,targetf:string);  
  2. var  
  3. FromF, ToF: file 
  4. NumRead, NumWritten: Integer;  
  5. Buf: array[1..2048of Char;  
  6. n:integer 
  7. begin  
  8.    AssignFile(FromF, sourcef);  
  9.    Reset(FromF, 1); Record size }  
  10.    AssignFile(ToF,targetf); Open output file }  
  11.    Rewrite(ToF, 1); Record size }  
  12.    n:=0 
  13.    repeat  
  14.         BlockRead(FromF, Buf, SizeOf(Buf), NumRead);  
  15.         form1.label1.caption:=IntToStr(sizeof(buf)*n*100 div FileSize(FromF))+'100%' 
  16.         application.ProcessMessages;  
  17.         //显示进度  
  18.         BlockWrite(ToF, Buf, NumRead, NumWritten);  
  19.         inc(n);  
  20.     until (NumRead 0or (NumWritten <> NumRead);  
  21.     form1.Label1.Caption:='100%' 
  22.     CloseFile(FromF);  
  23.     CloseFile(ToF);  
  24. end 
  25. procedure TForm1.Button1Click(Sender: TObject);  
  26. begin  
  27. mycopyfile('e:/components/tv2k-w2k.zip','c:/a.zip');  
  28. end 

****************************************************************************
22. cxGrid 设置斑马线
解决:
在TcxGridDBBandedTableView.Styles属性中有 ContentEven(奇数行风格) ContentOdd (偶数行风格) ,设定一下风格就好了。
****************************************************************************
23 根据记录内容更改字体颜色
解决:
参考范例CustomDrawTableViewDemo,
主要在TcxGridDBBandedTableView.OnCustomDrawCell事件中实现。
如下代码:

if   (Pos('-',AViewInfo.GridRecord.DisplayTexts[colOrderProductCount.Index]) > 0) then
begin //标识负数记录
    //ACanvas.Canvas.Brush.Color:= clMoneyGreen;
    ACanvas.Canvas.Font.Color:= clRed;//clActiveCaption
end;

其中colOrderProductCount是“产品订数”列。

还要有一步就是要刷新显示

TcxGridDBBandedTableView.LayoutChanged();
//tvCars.LayoutChanged(False);
TcxGridDBBandedTableView.Painter.Invalidate;

****************************************************************************
24 用代码展开/收缩主从结构
解决:
      Self.tvDepartment.ViewData.Expand(True); 
      Self.tvDepartment.ViewData.Collaspe(True); 
注:tvDepartment为主表对应的TableView

****************************************************************************
25 在内置右键菜单的后面增加菜单项
解决:
首先应在Form上加一个cxGridPopupMenu控件   以启用右键菜单 
UseBuildInPopupMenus设为True 

  1.      
  2. procedure   TFormItemList.FormCreate(Sender:   TObject);    
  3. var    
  4.       AMenu:   TComponent;    
  5.       FMenuItem,   FSubMenuItem:   TMenuItem;    
  6. begin    
  7.       AMenu   :=   nil   
  8.       if   cxGridPopupMenu.BuiltInPopupMenus.Count     0   then    
  9.           Exit;    
  10.       AMenu   :=   cxGridPopupMenu.BuiltInPopupMenus[0].PopupMenu; //第一个内置右键菜单(表头菜单)    
  11.       if   Assigned(AMenu)   and   AMenu.InheritsFrom(TPopupMenu)   then    
  12.       begin    
  13.           TPopupMenu(AMenu).AutoHotkeys   :=   maManual;         //手动热键    
  14.      
  15.           //-------------------------    
  16.           FMenuItem   :=   TMenuItem.Create(Self);    
  17.           FMenuItem.Caption   :=   '-'   
  18.           FMenuItem.Name   :=   'miLineForGroup'   
  19.           TPopupMenu(AMenu).Items.Add(FMenuItem);    
  20.      
  21.           //展开所有组    
  22.           FMenuItem   :=   TMenuItem.Create(Self);    
  23.           FMenuItem.Name   :=   'miExpandAllGroup'   
  24.           FMenuItem.Caption   :=   '展开所有组(&X)'   
  25.           FMenuItem.OnClick   :=   miExpandAllGroupClick;    
  26.           TPopupMenu(AMenu).Items.Add(FMenuItem);    
  27.      
  28.           //收缩所有组    
  29.           FMenuItem   :=   TMenuItem.Create(Self);    
  30.           FMenuItem.Name   :=   'miCollapseAllGroup'   
  31.           FMenuItem.Caption   :=   '收缩所有组(&O)'   
  32.           FMenuItem.OnClick   :=   miCollapseAllGroupClick;    
  33.           TPopupMenu(AMenu).Items.Add(FMenuItem);    
  34.      
  35.           //-------------------------    
  36.           FMenuItem   :=   TMenuItem.Create(Self);    
  37.           FMenuItem.Caption   :=   '-'   
  38.           TPopupMenu(AMenu).Items.Add(FMenuItem);    
  39.      
  40.           //过滤面板    
  41.           FMenuItem   :=   TMenuItem.Create(Self);    
  42.           FMenuItem.Name   :=   'miFilterPanel'   
  43.           FMenuItem.Caption   :=   '过滤面板(&P)'   
  44.           //自动显示    
  45.           FSubMenuItem   :=   TMenuItem.Create(Self);    
  46.           FSubMenuItem.Name   :=   'miFilterPanelAuto'   
  47.           FSubMenuItem.Caption   :=   '自动(&A)'   
  48.           FSubMenuItem.RadioItem   :=   True;    
  49.           FSubMenuItem.GroupIndex   :=   5//指定同一组    
  50.           FSubMenuItem.Checked   :=   True;    
  51.           FSubMenuItem.OnClick   :=   miFilterPanelClick;    
  52.           FMenuItem.Add(FSubMenuItem); //加入二级子菜单    
  53.           //总是显示    
  54.           FSubMenuItem   :=   TMenuItem.Create(Self);    
  55.           FSubMenuItem.Name   :=   'miFilterPanelAlways'   
  56.           FSubMenuItem.Caption   :=   '总是显示(&W)'   
  57.           FSubMenuItem.RadioItem   :=   True;    
  58.           FSubMenuItem.GroupIndex   :=   5   
  59.           FSubMenuItem.OnClick   :=   miFilterPanelClick;    
  60.           FMenuItem.Add(FSubMenuItem);    
  61.           //从不显示    
  62.           FSubMenuItem   :=   TMenuItem.Create(Self);    
  63.           FSubMenuItem.Name   :=   'miFilterPanelNerver'   
  64.           FSubMenuItem.Caption   :=   '从不显示(&N)'   
  65.           FSubMenuItem.RadioItem   :=   True;    
  66.           FSubMenuItem.GroupIndex   :=   5   
  67.           FSubMenuItem.OnClick   :=   miFilterPanelClick;    
  68.           FMenuItem.Add(FSubMenuItem);    
  69.           TPopupMenu(AMenu).Items.Add(FMenuItem);    
  70.      
  71.           //自定义过滤    
  72.           FMenuItem   :=   TMenuItem.Create(Self);    
  73.           FMenuItem.Name   :=   'miCustomFilter'   
  74.           FMenuItem.Caption   :=   '自定义过滤(&M)'   
  75.           FMenuItem.OnClick   :=   miCustomFilterClick;    
  76.           TPopupMenu(AMenu).Items.Add(FMenuItem);    
  77.      
  78.           //过滤管理器    
  79.           FMenuItem   :=   TMenuItem.Create(Self);    
  80.           FMenuItem.Name   :=   'miFilterBuilder'   
  81.           TPopupMenu(AMenu).Images.AddImage(FormMain.ImageListExtend,   44); //添加图标图像    
  82.           FMenuItem.ImageIndex   :=   TPopupMenu(AMenu).Images.Count     1//指定图标序号    
  83.           FMenuItem.Caption   :=   '过滤管理器'   
  84.           FMenuItem.OnClick   :=   Self.miFilterBuilderClick;    
  85.           TPopupMenu(AMenu).Items.Add(FMenuItem);    
  86.      
  87.           //---------------------    
  88.           FMenuItem   :=   TMenuItem.Create(Self);    
  89.           FMenuItem.Caption   :=   '-'   
  90.           TPopupMenu(AMenu).Items.Add(FMenuItem);    
  91.      
  92.           //导出    
  93.           FMenuItem   :=   TMenuItem.Create(Self);    
  94.           FMenuItem.Name   :=   'miExport'   
  95.           TPopupMenu(AMenu).Images.AddImage(FormMain.ImageListExtend,   37);    
  96.           FMenuItem.ImageIndex   :=   TPopupMenu(AMenu).Images.Count     1   
  97.           FMenuItem.Caption   :=   '导出(&E)'   
  98.           FMenuItem.OnClick   :=   Self.miExportClick;    
  99.           TPopupMenu(AMenu).Items.Add(FMenuItem);    
  100.      
  101.           //打印    
  102.           FMenuItem   :=   TMenuItem.Create(Self);    
  103.           FMenuItem.Name   :=   'miPrint'   
  104.           FMenuItem.Caption   :=   '打印(&P)'   
  105.           TPopupMenu(AMenu).Images.AddImage(FormMain.ImageListExtend,   14);    
  106.           FMenuItem.ImageIndex   :=   TPopupMenu(AMenu).Images.Count     1   
  107.           FMenuItem.OnClick   :=   Self.miPrintClick;    
  108.           TPopupMenu(AMenu).Items.Add(FMenuItem);    
  109.       end   
  110. end   
  111.      
  112. procedure   TFormItemList.miExportClick(Sender:   TObject);    
  113. var    
  114.       FileName,   FileExt,   msg:   String;    
  115. begin    
  116.       if   Self.aqyQuery.IsEmpty   then    
  117.       begin    
  118.           msg   :=   '没有导出数据...'   
  119.           Application.MessageBox(PChar(msg),   PChar(Application.Title),    
  120.               MB_OK   or   MB_IconWarning);    
  121.           Exit;    
  122.       end   
  123.      
  124.       Self.SaveDialogExport.Filter   :=   'Excel文件   (*.xls)|*.xls|XML文件   (*.xml)|*.xml'    
  125.             '|文本文件   (*.txt)|*.txt|网页文件   (*.html)|*.html'   
  126.       Self.SaveDialogExport.Title   :=   '导出为'   
  127.      
  128.       if   not   Self.SaveDialogExport.Execute   then    
  129.           Exit;    
  130.      
  131.       FileName   :=   Self.SaveDialogExport.FileName;    
  132.       FileExt   :=   LowerCase(ExtractFileExt(FileName));    
  133.       if   FileExt     '.xls'   then    
  134.           ExportGrid4ToExcel(FileName,   Self.cxGrid1)    
  135.       else   if   FileExt     '.xml'   then    
  136.           ExportGrid4ToXML(FileName,   Self.cxGrid1)    
  137.       else   if   FileExt     '.txt'   then    
  138.           ExportGrid4ToText(FileName,   Self.cxGrid1)    
  139.       else   if   FileExt     '.html'   then    
  140.           ExportGrid4ToHTML(FileName,   Self.cxGrid1)    
  141.       else    
  142.       begin    
  143.           msg   :=   '不支持的导出文件类型...'   
  144.           Application.MessageBox(PChar(msg),   PChar(Application.Title),    
  145.               MB_OK   or   MB_IconError);    
  146.           Exit;    
  147.       end   
  148.      
  149.       msg   :=   '导出完成...'   
  150.       Application.MessageBox(PChar(msg),   PChar(Application.Title),    
  151.           MB_OK   or   MB_IconInformation);    
  152. end   
  153.      
  154. procedure   TFormItemList.miPrintClick(Sender:   TObject);    
  155. begin    
  156.       //打印    
  157.       Self.dxComponentPrinter.Preview(True,   Self.dxComponentPrinterLink1);    
  158. end   
  159.      
  160. procedure   TFormItemList.cxGridPopupMenuPopup(ASenderMenu:   TComponent;    
  161.       AHitTest:   TcxCustomGridHitTest;   X,   Y:   Integer;   var   AllowPopup:   Boolean);    
  162. begin    
  163.       if   GetHitTypeByHitCode(AHitTest.HitTestCode)     gvhtColumnHeader   then //右击列标题时    
  164.       begin    
  165.           //if   tvResult.DataController.Groups.GroupingItemCount       then    
  166.           if   tvResult.GroupedColumnCount     0   then //有分组时显示    
  167.           begin    
  168.             TMenuItem(Self.FindComponent('miLineForGroup')).Visible   :=   True;    
  169.             TMenuItem(Self.FindComponent('miExpandAllGroup')).Visible   :=   True;    
  170.             TMenuItem(Self.FindComponent('miCollapseAllGroup')).Visible   :=   True;    
  171.           end    
  172.           else    
  173.           begin    
  174.             TMenuItem(Self.FindComponent('miLineForGroup')).Visible   :=   False;    
  175.             TMenuItem(Self.FindComponent('miExpandAllGroup')).Visible   :=   False;    
  176.             TMenuItem(Self.FindComponent('miCollapseAllGroup')).Visible   :=   False;    
  177.           end   
  178.       end   
  179. end   
  180.      
  181. procedure   TFormItemList.miFilterBuilderClick(Sender:   TObject);    
  182. begin    
  183.       //过滤管理器    
  184.       //弹出Filter   Builder   Dialog对话框    
  185.       tvResult.Filtering.RunCustomizeDialog;    
  186. end   
  187.      
  188. procedure   TFormItemList.miCustomFilterClick(Sender:   TObject);    
  189. var    
  190.       AHitTest:   TcxCustomGridHitTest;    
  191. begin    
  192.       //自定义过滤    
  193.       //弹出Custom   Filter   Dialog对话框    
  194.       AHitTest   :=   cxGridPopupMenu.HitTest;    
  195.       if   GetHitTypeByHitCode(AHitTest.HitTestCode)     gvhtColumnHeader   then //获得右击的列    
  196.           tvResult.Filtering.RunCustomizeDialog(TcxGridColumnHeaderHitTest(AHitTest).Column);    
  197. end   
  198.      
  199. procedure   TFormItemList.miFilterPanelClick(Sender:   TObject);    
  200. var    
  201.       mi:   TMenuItem;    
  202. begin    
  203.       //隐藏/显示过滤面板    
  204.       mi   :=   TMenuItem(Sender);    
  205.       mi.Checked   :=   True;    
  206.       if   mi.Name     'miFilterPanelAlways'   then    
  207.           tvResult.Filtering.Visible   :=   fvAlways    
  208.       else   if   mi.Name     'miFilterPanelNerver'   then    
  209.           tvResult.Filtering.Visible   :=   fvNever    
  210.       else    
  211.           tvResult.Filtering.Visible   :=   fvNonEmpty;    
  212. end   
  213.      
  214. procedure   TFormItemList.miExpandAllGroupClick(Sender:   TObject);    
  215. begin    
  216.       //展开所有组    
  217.       tvResult.DataController.Groups.FullExpand;    
  218. end   
  219.      
  220. procedure   TFormItemList.miCollapseAllGroupClick(Sender:   TObject);    
  221. begin    
  222.       //收缩所有组    
  223.       tvResult.DataController.Groups.FullCollapse;    
  224. end 

****************************************************************************
26 根据某列的值设定其它列的可编辑性
解决:
procedure   TFormUser.tvUserEditing(Sender:   TcxCustomGridTableView; 
      AItem:   TcxCustomGridTableItem;   var   AAllow:   Boolean); 
begin 
      //如果第三列值为True,则第4列不能修改 
      if   (tvUser.Controller.FocusedRecord.Values[2]    True)   and   (AItem.Index    4)   then 
          AAllow   :=   False 
      else 
          AAllow   :=   True; 
end;

****************************************************************************
27 保存/恢复Grid布局
解决:
网格左上角的自定义布局按钮:
TableView-?OptionsCustiomize?ColumnsQuickCustomization true;

  1. //恢复布局    
  2. IniFileName   :=   ExtractFilePath(Application.ExeName)     'Layout/'     Self.Name     '.ini'   
  3. if   FileExists(IniFileName)   then    
  4.       Self.tvResult.RestoreFromIniFile(IniFileName) //从布局文件中恢复    
  5. else    
  6. begin    
  7.       Self.tvResult.BeginUpdate;    
  8.       for     :=   0   to   Self.tvResult.ItemCount     1   do    
  9.           Self.tvResult.Items[i].ApplyBestFit; //调整为最佳宽度    
  10.       Self.tvResult.EndUpdate;    
  11. end   
  12.      
  13. //保存布局    
  14. IniFileName   :=   ExtractFilePath(Application.ExeName)     'Layout/'     Self.Name     '.ini'   
  15. if   not   DirectoryExists(ExtractFileDir(IniFileName))   then    
  16.       CreateDir(ExtractFileDir(IniFileName));    
  17. Self.tvResult.StoreToIniFile(IniFileName); //保存为布局文件  
  18.   
  19.   
  20. 实例:  
  21. IniFileName: string 
  22.   
  23. procedure TMainFM.FormCreate(Sender: TObject);     //窗体创建时读取布局  
  24. var i: Integer;  
  25. begin  
  26.    qyHed.Open;  
  27.    IniFileName := ExtractFilePath(Application.ExeName) '/Layout/' cxGrd.Owner.ClassName cxGrd.Name '.ini' 
  28.    if FileExists(IniFileName) then  
  29.       Self.cxTbv.RestoreFromIniFile(IniFileName) //从布局文件中恢复  
  30.    else  
  31.    begin  
  32.       Self.cxTbv.BeginUpdate;  
  33.       for := 0 to Self.cxTbv.ItemCount 1 do  
  34.          Self.cxTbv.Items[i].ApplyBestFit; //调整为最佳宽度  
  35.       Self.cxTbv.EndUpdate;  
  36.    end 
  37. end 
  38.   
  39. procedure TMainFM.NSaveGrdClick(Sender: TObject);      //保存布局文件  
  40. begin  
  41.    try  
  42.       IniFileName := ExtractFilePath(Application.ExeName) '/Layout/' cxGrd.Owner.ClassName cxGrd.Name '.ini' 
  43.       if not DirectoryExists(ExtractFileDir(IniFileName)) then  
  44.          CreateDir(ExtractFileDir(IniFileName));  
  45.       Self.cxTbv.StoreToIniFile(IniFileName);  
  46.    except  
  47.    end 
  48. end 

****************************************************************************

28保存/恢复带汇总行的布局解决:
.StoreToIniFile('c:/Grid.ini',   True,   [gsoUseSummary]);   
.RestoreFromIniFile(,True,False{or True,optional},[gsoUseSummary]);

 zj:本条与50条重复

****************************************************************************

28 在主从TableView中根据主TableView得到对应的从TableView
解决:

var 
      ADetailDC:   TcxGridDataController; 
      AView:   TcxCustomGridTableView; 
begin 
      with   cxGrid1DBTableView1.DataController   do 
          ADetailDC   :=   TcxGridDataController(GetDetailDataController(FocusedRecordIndex,   0)); 
      AView   :=   ADetailDC.GridView; 
end;

 

==============================================================================

29 定位在第一行并显示内置编辑器

cxDBVerticalGrid1.FocusedRow := cxDBVerticalGrid1.Rows[0];
cxDBVerticalGrid1.ShowEdit;

==============================================================================

30 隐藏 "" 字符串

该文本存储在scxGridNoDataInfoText资源字符串,可以将该资源字符串的内容设为空
来隐藏该文本。

uses cxClasses, cxGridStrs;
...
cxSetResourceString(@scxGridNoDataInfoText, '');

//如果"" 字符串已经显示,需要调用:
.LayoutChanged;

============================================================

31 删除应用过滤后的行

var
I: Integer;
begin
with do
for I := 0 to ViewData.RecordCount - 1 do
begin
ViewData.Records[0].Focused := True;
DataController.DataSet.Delete;
end;

=============================================================
 

32 根据单元的值设置样式 
解决:
procedure   .StylesGetContentStyle( 
      Sender:   TcxCustomGridTableView;   ARecord:   TcxCustomGridRecord; 
      AItem:   TcxCustomGridTableItem;   out   AStyle:   TcxStyle); 
begin 
      if   ARecord.Values[AItem.Index]    aSomeValue   then 
          AStyle   :=  
end; 
  
procedure   .StylesGetContentStyle( 
      Sender:   TcxCustomGridTableView;   ARecord:   TcxCustomGridRecord; 
      AItem:   TcxCustomGridTableItem;   out   AStyle:   TcxStyle); 
var 
      AColumn:   TcxCustomGridTableItem; 
begin 
      AColumn   :=   (Sender   as   TcxGridDBTableView).GetColumnByFieldName('Email'); 
      if   VarToStr(ARecord.Values[AColumn.Index])    ''   then 
          AStyle   :=   cxStyleNullEmail; 
end; 
  
======================================================================
  
TcxCustomGridTableView.FindItemByName,   TcxGridDBTableView.GetColumnByFieldName   or 
TcxGridDBDataController.GetItemByFieldName 
  
      with   cxGrid1DBBandedTableView1.DataController   do 
          AValue   :=   Values[FocusedRecordIndex,   GetItemByFieldName('SomeFieldName').Index]; 
  
****************************************************************************
33 动态生成BandedView
解决:
var 
      AView:   TcxCustomGridView; 
begin 
      AView   :=   .CreateView(TcxGridDBBandedTableView); 
      TcxGridDBBandedTableView(AView).DataController.DataSource   :=  
      TcxGridDBBandedTableView(AView).Bands.Add; 
      with   TcxGridDBBandedTableView(AView).Bands.Add   do 
      begin 
          Visible   :=   False; 
          FixedKind   :=   fkLeft; 
      end; 
      TcxGridDBBandedTableView(AView).DataController.CreateAllItems; 
      .GridView   :=   AView;
end;
****************************************************************************
34 当底层数据集为空时显示一条空记录
解决:
procedure  

.Enter(Sender:   TObject); 
var 
      View:   TcxGridDBTableView; 
begin 
      View   :=   TcxGridDBTableView((Sender   as   TcxGrid).FocusedView); 
      if   View.DataController.DataSet.IsEmpty   then 
      begin 
          View.DataController.DataSet.Append; 
          View.Controller.EditingController.ShowEdit; 
      end; 
end;
****************************************************************************
原文地址:https://www.cnblogs.com/luckForever/p/7255057.html