博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cxGrid用法-最新
阅读量:5145 次
发布时间:2019-06-13

本文共 37879 字,大约阅读时间需要 126 分钟。

cxGrid用法步 1.你先放一个cxGrid,设置好View,设置View.DataController连接的DataSource2.激活DataSource连接的DataSet,双击cxGrid,点击Retrieve Fields,取得所有的Column3.设置View的OptionsView.Footer=True,OptionsView.GroupFooters=True,这是为了把分组小计和总计面板显示出来4.将“订单号”字段拖到cxGrid上方的分组面板(GroupbyBox),将数据按“订单号”分组。这时你会发现单身所有的数据都缩起来了,如果想使所有的数据都展开,可以设置View.DataController.Options.dcoGroupsAlwaysExpanded=True5.设置分组小计:把View.DataController.Summary.DefaultGroupSummaryItems点开,新增一个Item,Column属性在下拉里选择“数量”字段,FieldName属性为空,Format属性可以设置数值的显示格式,Kind属性下拉skSum加总,Position属性一定要选择spFooter。6.设置总计:把View.DataController.Summary.FooterSummaryItems点开,新增一个Item,Column属性在下拉里选择“数量”字段,FieldName属性为空,Format属性可以设置数值的显示格式,Kind属性下拉skSum加总,Position属性一定要选择spFooter。大功告成,按F9看一下胜利果实吧。再奉送一个技巧,在Form1再放一个TcxGridPopupMenu控件,就在cxGrid控件旁边的那个,把TcxGridPopupMenu的Grid属性设置成你的cxGrid。然后运行程序,在运行状态,点击Grid上的所有地方,左键或右键,你都会有意外收获。

(1)动态设置显示格式procedure SetDisplayFormat(ACtrlData: TClientDataSet;  TbView: TcxGridDBTableView);var  i: integer;begin  if ACtrlData.RecordCount <= 0 then Exit;  try    TbView.ClearItems;    ACtrlData.First;    for i := 0 to ACtrlData.RecordCount - 1 do    begin      if ACtrlData.FieldByName('SQBF_DisplayInGrid').AsString = '1' then //在表格中显示      with TbView.CreateColumn do      begin        DataBinding.FieldName := ACtrlData.FieldByName('SQBF_FieldName').AsString;        Caption := ACtrlData.FieldByName('SQBF_Caption').AsString; //字段中文标题        Hint := ACtrlData.FieldByName('SQBF_Hint').AsString;        Width := ACtrlData.FieldByName('SQBF_Width').AsInteger;        HeaderAlignmentHorz := taCenter;      end;      ACtrlData.Next;    end;  except    on E: Exception do      SaveLog('设置显示格式时出错:' + E.Message);  end;end;(2)显示行号procedure TFmQueryBase.cxDBViewMasterCustomDrawIndicatorCell(  Sender: TcxGridTableView; ACanvas: TcxCanvas;  AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean);var  FValue: string;  FBounds: TRect;begin  FBounds := AViewInfo.Bounds;  if (AViewInfo is TcxGridIndicatorRowItemViewInfo) then  begin    ACanvas.FillRect(FBounds);    ACanvas.DrawComplexFrame(FBounds, clBlack, clBlack, [bBottom, bLeft, bRight], 1);    FValue := IntToStr(TcxGridIndicatorRowItemViewInfo(AViewInfo).GridRecord.Index+1);    InflateRect(FBounds, -3, -2); //Platform specific. May not work on Linux.    ACanvas.Font.Color := clBlack;    ACanvas.Brush.Style := bsClear;    ACanvas.DrawText(FValue, FBounds, cxAlignCenter or cxAlignTop);    ADone := True;  end;end;(3)设置显示格式,我的项目要求先动态添加字段,这时不知道字段类型,所以设置DisplayFormat不方便,我还没有找到好方法。所以采用打开数据集后再设置:procedure TFmQueryBase.cdsMasterAfterOpen(DataSet: TDataSet);var  i: Integer;begin  for i := 0 to cxDBViewMaster.DataController.DataSet.FieldCount -1 do  begin    if cxDBViewMaster.DataController.DataSet.Fields[i] is TNumericField then    begin      if Pos('AMOUNT', UpperCase(cxDBViewMaster.DataController.DataSet.Fields[i].FieldName)) > 0 then      begin        TNumericField(cxDBViewMaster.DataController.DataSet.Fields[i]).DisplayFormat := '#,##0.000';        Continue;      end;      if Pos('QUANTITY', UpperCase(cxDBViewMaster.DataController.DataSet.Fields[i].FieldName)) > 0 then      begin        TNumericField(cxDBViewMaster.DataController.DataSet.Fields[i]).DisplayFormat := '#,##0.000';        Continue;      end;       if Pos('MONEY', UpperCase(cxDBViewMaster.DataController.DataSet.Fields[i].FieldName)) > 0 then      begin        TNumericField(cxDBViewMaster.DataController.DataSet.Fields[i]).DisplayFormat := '#,##0.00';        Continue;      end;   end;  end;end; 2007-7-19 12:48:54     查看评语»»»      2007-7-19 12:53:09    别人的,转载http://www.showding.cn/item/cxGrid__182526.aspx最近在学习使用cxGrid,安装的版本是ExpressQuantumGrid   Suite   v5.10     我发现这个控件功能虽然强大,但是非常难用。         现在我手头就有几个问题还没解决:     1)主从模式下导出Excel中文会产生乱码,而且从表内容没有导出。     我不知道是不是因为我的字段名包括单引号的原因。     导出代码:ExportGrid4ToExcel(FileName,   cxGrid);         2)主从模式下通过按钮对从表添加/删除行,代码怎么写。     附:单表添加/删除行的代码     procedure   TFormAccount.cxButtonNewClick(Sender:   TObject);     begin         Self.tvAccount.DataController.Append;         Self.tvAccount.Columns[0].Focused   :=   True;         cxGrid.SetFocus;     end;         procedure   TFormAccount.cxButtonDeleteClick(Sender:   TObject);     begin         if   Self.tvAccount.DataController.RowCount   =   0   then             Exit;         if   Application.MessageBox('确认删除当前记录?',   '确认删除',             MB_YesNo   +   MB_IconQuestion)   =   IDNO   then             Exit;         Self.tvAccount.DataController.DeleteFocused;     end;         3)动态创建主从结构出错(Compiler没错,运行时出现系统错误0000000018),     我使用了二个ADOStoreProcedure作主从表     代码如下:     var         Level:   TcxGridLevel;         GridView:   TcxGridDBTableView;     begin         Level   :=   cxGrid1.Levels[0].Add;         GridView   :=   TcxGridDBTableView(cxGrid1.CreateView(TcxGridDBTableView));         GridView.DataController.DataSource   :=   Self.dsDetail;             GridView.DataController.KeyFieldNames   :=   'PurchOrderID;POLineNbr;PromiseDate;ReceiverDate';         GridView.DataController.MasterKeyFieldNames   :=   'VendorID';         GridView.DataController.DetailKeyFieldNames   :=   'VendorID';         GridView.DataController.DataModeController.SmartRefresh   :=   True;             GridView.OptionsCustomize.ColumnHiding   :=   True;         GridView.OptionsCustomize.ColumnsQuickCustomization   :=   True;         GridView.OptionsData.Deleting   :=   False;         GridView.OptionsData.Inserting   :=   False;         GridView.OptionsView.Indicator   :=   True;         Level.GridView   :=   GridView;             GridView   :=   TcxGridDBTableView(cxGrid1.Levels[0].GridView);         GridView.DataController.KeyFieldNames   :=   'VendorID';         GridView.OptionsView.GroupByBox   :=   False;             //显示主表内容         tvResult.BeginUpdate;         tvResult.ClearItems;         tvResult.DataController.CreateAllItems;         tvResult.EndUpdate;             //显示明细表内容         GridView   :=   TcxGridDBTableView(cxGrid1.Levels[0].Items[0].GridView);         GridView.BeginUpdate;         GridView.ClearItems;         GridView.DataController.CreateAllItems;         GridView.DataController.Refresh;         GridView.EndUpdate;     end;     此楼回复Re:  --------------------------------------------------------------------------------小技巧:用代码展开/收缩主从结构     Self.tvDepartment.ViewData.Expand(True);     Self.tvDepartment.ViewData.Collaspe(True);     注:tvDepartment为主表对应的TableView此楼回复Re:  --------------------------------------------------------------------------------你说的这几个问题我也遇到过。     第一个问题是编码的问题,修改了其中关于编码的函数,OK.     第二个问题在cxGrid的社区可以找到解答,但从表必须满足某种条件,例如关键字排序。     第三个问题的解决办法,你可以尝试在动态创建的代码前后加上:     grid.beginupdate;     ...     grid.endupdate     来解决。此楼回复Re:  --------------------------------------------------------------------------------没用过     不要经常使用三方控件此楼回复Re:  --------------------------------------------------------------------------------to   tttk(网络芝麻):     第一个问题:如何修改啊,贴出代码     第二个问题:没搜到啊     第三个问题:试一下再说此楼回复Re:  --------------------------------------------------------------------------------不要经常使用三方控件     ======================     我感觉不用cxGrid的话,没必要用Delphi了,呵呵此楼回复Re:  --------------------------------------------------------------------------------樓上這話是不是有點問題?DELPHI能做得事情很多很多,難道非要用CXGRID?CXGRID不是用DELPHI做出來得?此楼回复Re:  --------------------------------------------------------------------------------没用过.....此楼回复Re:  --------------------------------------------------------------------------------回复人:   zxkid(没有人会像我这样...)   (   )   信誉:101     2006-01-06   16:58:00     得分:   0                           不要经常使用三方控件     ======================     我感觉不用cxGrid的话,没必要用Delphi了,呵呵                   **********     楼主乃天人也!!此楼回复Re:  --------------------------------------------------------------------------------呵呵此楼回复Re:  --------------------------------------------------------------------------------cxGrid比较不错,我也使用过导出到Excel,没有遇到你说的乱码         主从表也没有问题的,其实跟单表操作还不是一回事此楼回复Re:  --------------------------------------------------------------------------------up此楼回复Re:  --------------------------------------------------------------------------------没用过cxGrid,以后考虑此楼回复Re:  --------------------------------------------------------------------------------楼主乃天人也!!     =============================     Delphi下有cxGrid,   .NET下有XtraGrid,   它们都是同一公司出的。     迟早都会转到.NET,所以。。。此楼回复Re:  --------------------------------------------------------------------------------路过此楼回复Re:  --------------------------------------------------------------------------------用过,挺好,只会使用最简单的。此楼回复Re:  --------------------------------------------------------------------------------发一个邮件给我,我把解决乱码后的源代码发一分给你,放到你的项目文件夹下即可。     tttk2000@hotmail.com此楼回复Re:  --------------------------------------------------------------------------------第二个问题:https://www.devexpress.com/Support/Center/default.aspx?view=ViewIssue&issueid=B2691此楼回复Re:  --------------------------------------------------------------------------------谢谢tttk(网络芝麻)           第二个问题:我现在直接让用户用导航条的删除/添加按钮了。根据你给的网址上的内容我知道大概该怎么写了,有空再试试。         第一个问题:不光是乱码问题,还有从表内容没导出的问题。     只有一个表的话是不会出现乱码的。         第三个问题:还没来得及试。此楼回复Re:  --------------------------------------------------------------------------------第一个问题:看了一下帮助,原来cxGrid不支持主从表的导出,只能导出主表(顶层表)的内容。晕此楼回复Re:  --------------------------------------------------------------------------------贴一些小技巧,希望与各位使用cxGrid的朋友共同交流     各位有什么好个技巧也可以贴出来:         技巧二:在内置右键菜单的后面增加菜单项         首先应在Form上加一个cxGridPopupMenu控件   以启用右键菜单     UseBuildInPopupMenus设为True         procedure   TFormItemList.FormCreate(Sender:   TObject);     var         AMenu:   TComponent;         FMenuItem,   FSubMenuItem:   TMenuItem;     begin         AMenu   :=   nil;         if   cxGridPopupMenu.BuiltInPopupMenus.Count   =   0   then             Exit;         AMenu   :=   cxGridPopupMenu.BuiltInPopupMenus[0].PopupMenu; //第一个内置右键菜单(表头菜单)         if   Assigned(AMenu)   and   AMenu.InheritsFrom(TPopupMenu)   then         begin             TPopupMenu(AMenu).AutoHotkeys   :=   maManual;         //手动热键                 //-------------------------             FMenuItem   :=   TMenuItem.Create(Self);             FMenuItem.Caption   :=   '-';             FMenuItem.Name   :=   'miLineForGroup';             TPopupMenu(AMenu).Items.Add(FMenuItem);                 //展开所有组             FMenuItem   :=   TMenuItem.Create(Self);             FMenuItem.Name   :=   'miExpandAllGroup';             FMenuItem.Caption   :=   '展开所有组(&X)';             FMenuItem.OnClick   :=   miExpandAllGroupClick;             TPopupMenu(AMenu).Items.Add(FMenuItem);                 //收缩所有组             FMenuItem   :=   TMenuItem.Create(Self);             FMenuItem.Name   :=   'miCollapseAllGroup';             FMenuItem.Caption   :=   '收缩所有组(&O)';             FMenuItem.OnClick   :=   miCollapseAllGroupClick;             TPopupMenu(AMenu).Items.Add(FMenuItem);                 //-------------------------             FMenuItem   :=   TMenuItem.Create(Self);             FMenuItem.Caption   :=   '-';             TPopupMenu(AMenu).Items.Add(FMenuItem);                 //过滤面板             FMenuItem   :=   TMenuItem.Create(Self);             FMenuItem.Name   :=   'miFilterPanel';             FMenuItem.Caption   :=   '过滤面板(&P)';             //自动显示             FSubMenuItem   :=   TMenuItem.Create(Self);             FSubMenuItem.Name   :=   'miFilterPanelAuto';             FSubMenuItem.Caption   :=   '自动(&A)';             FSubMenuItem.RadioItem   :=   True;             FSubMenuItem.GroupIndex   :=   5; //指定同一组             FSubMenuItem.Checked   :=   True;             FSubMenuItem.OnClick   :=   miFilterPanelClick;             FMenuItem.Add(FSubMenuItem); //加入二级子菜单             //总是显示             FSubMenuItem   :=   TMenuItem.Create(Self);             FSubMenuItem.Name   :=   'miFilterPanelAlways';             FSubMenuItem.Caption   :=   '总是显示(&W)';             FSubMenuItem.RadioItem   :=   True;             FSubMenuItem.GroupIndex   :=   5;             FSubMenuItem.OnClick   :=   miFilterPanelClick;             FMenuItem.Add(FSubMenuItem);             //从不显示             FSubMenuItem   :=   TMenuItem.Create(Self);             FSubMenuItem.Name   :=   'miFilterPanelNerver';             FSubMenuItem.Caption   :=   '从不显示(&N)';             FSubMenuItem.RadioItem   :=   True;             FSubMenuItem.GroupIndex   :=   5;             FSubMenuItem.OnClick   :=   miFilterPanelClick;             FMenuItem.Add(FSubMenuItem);             TPopupMenu(AMenu).Items.Add(FMenuItem);                 //自定义过滤             FMenuItem   :=   TMenuItem.Create(Self);             FMenuItem.Name   :=   'miCustomFilter';             FMenuItem.Caption   :=   '自定义过滤(&M)';             FMenuItem.OnClick   :=   miCustomFilterClick;             TPopupMenu(AMenu).Items.Add(FMenuItem);                 //过滤管理器             FMenuItem   :=   TMenuItem.Create(Self);             FMenuItem.Name   :=   'miFilterBuilder';             TPopupMenu(AMenu).Images.AddImage(FormMain.ImageListExtend,   44); //添加图标图像             FMenuItem.ImageIndex   :=   TPopupMenu(AMenu).Images.Count   -   1; //指定图标序号             FMenuItem.Caption   :=   '过滤管理器';             FMenuItem.OnClick   :=   Self.miFilterBuilderClick;             TPopupMenu(AMenu).Items.Add(FMenuItem);                 //---------------------             FMenuItem   :=   TMenuItem.Create(Self);             FMenuItem.Caption   :=   '-';             TPopupMenu(AMenu).Items.Add(FMenuItem);                 //导出             FMenuItem   :=   TMenuItem.Create(Self);             FMenuItem.Name   :=   'miExport';             TPopupMenu(AMenu).Images.AddImage(FormMain.ImageListExtend,   37);             FMenuItem.ImageIndex   :=   TPopupMenu(AMenu).Images.Count   -   1;             FMenuItem.Caption   :=   '导出(&E)';             FMenuItem.OnClick   :=   Self.miExportClick;             TPopupMenu(AMenu).Items.Add(FMenuItem);                 //打印             FMenuItem   :=   TMenuItem.Create(Self);             FMenuItem.Name   :=   'miPrint';             FMenuItem.Caption   :=   '打印(&P)';             TPopupMenu(AMenu).Images.AddImage(FormMain.ImageListExtend,   14);             FMenuItem.ImageIndex   :=   TPopupMenu(AMenu).Images.Count   -   1;             FMenuItem.OnClick   :=   Self.miPrintClick;             TPopupMenu(AMenu).Items.Add(FMenuItem);         end;     end;         procedure   TFormItemList.miExportClick(Sender:   TObject);     var         FileName,   FileExt,   msg:   String;     begin         if   Self.aqyQuery.IsEmpty   then         begin             msg   :=   '没有导出数据...';             Application.MessageBox(PChar(msg),   PChar(Application.Title),                 MB_OK   or   MB_IconWarning);             Exit;         end;             Self.SaveDialogExport.Filter   :=   'Excel文件   (*.xls)|*.xls|XML文件   (*.xml)|*.xml'             +   '|文本文件   (*.txt)|*.txt|网页文件   (*.html)|*.html';         Self.SaveDialogExport.Title   :=   '导出为';             if   not   Self.SaveDialogExport.Execute   then             Exit;             FileName   :=   Self.SaveDialogExport.FileName;         FileExt   :=   LowerCase(ExtractFileExt(FileName));         if   FileExt   =   '.xls'   then             ExportGrid4ToExcel(FileName,   Self.cxGrid1)         else   if   FileExt   =   '.xml'   then             ExportGrid4ToXML(FileName,   Self.cxGrid1)         else   if   FileExt   =   '.txt'   then             ExportGrid4ToText(FileName,   Self.cxGrid1)         else   if   FileExt   =   '.html'   then             ExportGrid4ToHTML(FileName,   Self.cxGrid1)         else         begin             msg   :=   '不支持的导出文件类型...';             Application.MessageBox(PChar(msg),   PChar(Application.Title),                 MB_OK   or   MB_IconError);             Exit;         end;             msg   :=   '导出完成...';         Application.MessageBox(PChar(msg),   PChar(Application.Title),             MB_OK   or   MB_IconInformation);     end;         procedure   TFormItemList.miPrintClick(Sender:   TObject);     begin         //打印         Self.dxComponentPrinter.Preview(True,   Self.dxComponentPrinterLink1);     end;         procedure   TFormItemList.cxGridPopupMenuPopup(ASenderMenu:   TComponent;         AHitTest:   TcxCustomGridHitTest;   X,   Y:   Integer;   var   AllowPopup:   Boolean);     begin         if   GetHitTypeByHitCode(AHitTest.HitTestCode)   =   gvhtColumnHeader   then //右击列标题时         begin             //if   tvResult.DataController.Groups.GroupingItemCount   >   0   then             if   tvResult.GroupedColumnCount   >   0   then //有分组时显示             begin               TMenuItem(Self.FindComponent('miLineForGroup')).Visible   :=   True;               TMenuItem(Self.FindComponent('miExpandAllGroup')).Visible   :=   True;               TMenuItem(Self.FindComponent('miCollapseAllGroup')).Visible   :=   True;             end             else             begin               TMenuItem(Self.FindComponent('miLineForGroup')).Visible   :=   False;               TMenuItem(Self.FindComponent('miExpandAllGroup')).Visible   :=   False;               TMenuItem(Self.FindComponent('miCollapseAllGroup')).Visible   :=   False;             end;         end;     end;         procedure   TFormItemList.miFilterBuilderClick(Sender:   TObject);     begin         //过滤管理器         //弹出Filter   Builder   Dialog对话框         tvResult.Filtering.RunCustomizeDialog;     end;         procedure   TFormItemList.miCustomFilterClick(Sender:   TObject);     var         AHitTest:   TcxCustomGridHitTest;     begin         //自定义过滤         //弹出Custom   Filter   Dialog对话框         AHitTest   :=   cxGridPopupMenu.HitTest;         if   GetHitTypeByHitCode(AHitTest.HitTestCode)   =   gvhtColumnHeader   then //获得右击的列             tvResult.Filtering.RunCustomizeDialog(TcxGridColumnHeaderHitTest(AHitTest).Column);     end;         procedure   TFormItemList.miFilterPanelClick(Sender:   TObject);     var         mi:   TMenuItem;     begin         //隐藏/显示过滤面板         mi   :=   TMenuItem(Sender);         mi.Checked   :=   True;         if   mi.Name   =   'miFilterPanelAlways'   then             tvResult.Filtering.Visible   :=   fvAlways         else   if   mi.Name   =   'miFilterPanelNerver'   then             tvResult.Filtering.Visible   :=   fvNever         else             tvResult.Filtering.Visible   :=   fvNonEmpty;     end;         procedure   TFormItemList.miExpandAllGroupClick(Sender:   TObject);     begin         //展开所有组         tvResult.DataController.Groups.FullExpand;     end;         procedure   TFormItemList.miCollapseAllGroupClick(Sender:   TObject);     begin         //收缩所有组         tvResult.DataController.Groups.FullCollapse;     end;     此楼回复Re:  --------------------------------------------------------------------------------在用,留名此楼回复Re:  --------------------------------------------------------------------------------技巧三   按条件计算合计值         在Footer的第一列显示[合计:]     加一个Summary项,Column设为Grid的第一列,Kind设为skNone     在该Summary项的OnGetText事件中,输入:     procedure   TFormExpense.tvExpenseTcxGridDBDataControllerTcxDataSummaryFooterSummaryItems2GetText(         Sender:   TcxDataSummaryItem;   const   AValue:   Variant;   AIsFooter:   Boolean;         var   AText:   String);     begin         AText   :=   '合计:';     end;         按条件汇总:     在TableView的DataController->Summary->FooterSummary->OnSummary事件中,输入:     procedure   TFormExpense.tvExpenseDataControllerSummaryFooterSummaryItemsSummary(         ASender:   TcxDataSummaryItems;   Arguments:   TcxSummaryEventArguments;         var   OutArguments:   TcxSummaryEventOutArguments);     begin         //得到字段名   TcxDBDataSummaryItem(Arguments.SummaryItem).FieldName;         if   (ASender.DataController.Values[Arguments.RecordIndex,   tvExpenseLevel.Index]   >   1)       //只统计Level列=1的值             and   (TcxDBDataSummaryItem(Arguments.SummaryItem).Kind   =   skSum)   then             OutArguments.Value   :=   0; //Level   >   1的统计值设为0     end;     此楼回复Re:  --------------------------------------------------------------------------------借贵地一用,问个CXGrid问题,在cxgrid中如何使一些行不能编辑,如:字段isenable   =   false的行此楼回复Re:  --------------------------------------------------------------------------------楼上的问题     请参考下面的技巧         技巧四:根据某列的值设定其它列的可编辑性         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;     此楼回复Re:  --------------------------------------------------------------------------------技巧五:保存/恢复Grid布局         //恢复布局     IniFileName   :=   ExtractFilePath(Application.ExeName)   +   'Layout\'   +   Self.Name   +   '.ini';     if   FileExists(IniFileName)   then         Self.tvResult.RestoreFromIniFile(IniFileName) //从布局文件中恢复     else     begin         Self.tvResult.BeginUpdate;         for   i   :=   0   to   Self.tvResult.ItemCount   -   1   do             Self.tvResult.Items[i].ApplyBestFit; //调整为最佳宽度         Self.tvResult.EndUpdate;     end;         //保存布局     IniFileName   :=   ExtractFilePath(Application.ExeName)   +   'Layout\'   +   Self.Name   +   '.ini';     if   not   DirectoryExists(ExtractFileDir(IniFileName))   then         CreateDir(ExtractFileDir(IniFileName));     Self.tvResult.StoreToIniFile(IniFileName); //保存为布局文件     此楼回复Re:  --------------------------------------------------------------------------------借用地问一下:在   cxgrid中,如果我同时选中主表与子表中的记录,怎么样能同时进行对其所选记录进行处理呢。     我现在只能判断   焦点是在主表还是从表中,然后只能对主表或子表中的数据进行处理。     此楼回复Re:  --------------------------------------------------------------------------------看来用cxGrid人不多啊         再多贴一些技巧,需要的朋友顶一下         ==========================================================================         在主从TableView中根据主TableView得到对应的从TableView     var         ADetailDC:   TcxGridDataController;         AView:   TcxCustomGridTableView;     begin         with   cxGrid1DBTableView1.DataController   do             ADetailDC   :=   TcxGridDataController(GetDetailDataController(FocusedRecordIndex,   0));         AView   :=   ADetailDC.GridView;     end;         ==============================================================================         定位在第一行并显示内置编辑器         cxDBVerticalGrid1.FocusedRow   :=   cxDBVerticalGrid1.Rows[0];     cxDBVerticalGrid1.ShowEdit;         ==============================================================================         隐藏   "
" 字符串 该文本存储在scxGridNoDataInfoText资源字符串,可以将该资源字符串的内容设为空 来隐藏该文本。 uses cxClasses, cxGridStrs; ... cxSetResourceString(@scxGridNoDataInfoText, ''); //如果"
" 字符串已经显示,需要调用:
.LayoutChanged; ============================================================ 删除应用过滤后的行 var I: Integer; begin with
do for I := 0 to ViewData.RecordCount - 1 do begin ViewData.Records[0].Focused := True; DataController.DataSet.Delete; end; ============================================================= 根据单元的值设置样式 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]; =================================================================== 动态生成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; 此楼回复Re: --------------------------------------------------------------------------------====================================================================== 当底层数据集为空时显示一条空记录 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; ======================================================================= 在当前View插入记录 使用FocusedView属性得到当前焦点View,用View.DataController得到对应的Data Controller, 之后使用Data Controller的方法来操作数据: - Append - Insert - Post - Cancel - DeleteFocused - DeleteSelection 示例: var ARecIndex: Integer; … View.DataController.Append; ARecIndex := View.DataController.FocusedRecordIndex; View.DataController.Values[ARecIndex, SomeItemIndex] := SomeValue; View.DataController.Post; 另外一种方法是使用View.DataController.DataSource.DataSet得到底层数据集后,再用数据集的 方法来操作数据。 ======================================================================== 激活内置编辑控件 1)
.Controller.EditingController.ShowEdit(
); 2)
.Controller.EditingController.StartEditShowingTimer(
); 3)
.Controller.EditingItem :=
; 4)
.Editing := True; 隐藏内置编辑控件
.Controller.EditingController.HideEdit(True); =========================================================================== 移除一个分组列
.GroupIndex := -1;
.Visible := True; =========================================================================== 保存修改到数据库 procedure
.FormClose(Sender: TObject; var Action: TCloseAction); begin if (
.FocusedView <> nil) and (
.FocusedView.DataController.EditState <> []) then
.FocusedView.DataController.Post; end; ============================================================================ 设置内置右键菜单 内置右键菜单包括二个菜单:cxGridStdHeaderMenu, TcxGridStdFooterMenu uses cxGridStdPopupMenu; procedure TForm1.cxGridPopupMenu1Popup(ASenderMenu: TComponent; AHitTest: TcxCustomGridHitTest; X, Y: Integer; var AllowPopup: Boolean); begin if ASenderMenu is TcxGridStdHeaderMenu then TcxGridStdHeaderMenu(ASenderMenu).OnPopup := StdHeaderMenuPopup; end; procedure TForm1.StdHeaderMenuPopup(Sender: TObject); var I: Integer; begin with TcxGridStdHeaderMenu(Sender).Items do for I := 0 to Count - 1 do if Items[I].Caption = 'Group By Box' then begin Items[I].Enabled := False; System.Break; end end; =========================================================================== 得到选中记录的值 1) View.DataController.DataModeController.GridMode = False时 RecIdx := View.Controller.SelectedRecords[i].RecordIndex; ColIdx := View.DataController.GetItemByFieldName(AFieldName).Index; OutputVal := View.DataController.Values[RecIdx, ColIdx]; //RecID := View.DataController.GetRecordId(RecIdx); //OutputVal := ADataSet.Lookup(View.DataController.KeyFieldNames, RecID, AFieldName); 2) View.DataController.DataModeController.GridMode = True时 Bkm := View.DataController.GetSelectedBookmark(ASelectedRecordIndex); if ADataSet.BookmarkValid(TBookmark(Bkm)) then begin ADataSet.Bookmark := TBookmark(Bkm); OutputVal := ADataSet.FieldByName(AFieldName).Value; end; View.BeginUpdate; View.DataController.BeginLocate; try // make changes here… finally View.DataController.EndLocate; View.EndUpdate; end; ============================================================= 在GridMode禁用内置的右键Footer菜单 uses cxGridStdPopupMenu; procedure cxGridPopupMenuOnPopup(...) begin if (ASenderMenu is TcxGridStdFooterMenu) and
.DataController.DataModeController.GridMode then AllowPopup := False; end; ============================================================== 主从表任何时候只能展开一个组 procedure TForm1.ADetailDataControllerCollapsing( ADataController: TcxCustomDataController; ARecordIndex: Integer; var AAllow: Boolean); var I: Integer; C: Integer; begin AAllow := False; C := 0; for I := 0 to ADataController.RecordCount - 1 do begin if ADataController.GetDetailExpanding(I) then Inc(C); if C > 1 then AAllow := True; end; end; procedure TForm1.ADetailDataControllerExpanding( ADataController: TcxCustomDataController; ARecordIndex: Integer; var AAllow: Boolean); begin ADataController.CollapseDetails; end; procedure TForm1.FormCreate(Sender: TObject); begin cxGrid1DBTableView1.DataController.OnDetailExpanding := ADetailDataControllerExpanding; cxGrid1DBTableView1.DataController.OnDetailCollapsing := ADetailDataControllerCollapsing; end; ================================================================= 动态创建层次(Level)和视图(View) var Grid: TcxGrid; Level: TcxGridLevel; View: TcxGridDBTableView; begin // Creates a Grid instance Grid := TcxGrid.Create(SomeOwner); Grid.Parent := SomeParent; // Creates a Level Level := Grid.Levels.Add; Level.Name := 'SomeLevelName'; // Creates a View View := Grid.CreateView(TcxGridDBTableView) as TcxGridDBTableView; View.Name := 'SomeViewName'; // … and binds it to the Level Level.GridView := View; // Hooks up the View to the data View.DataController.DataSource := SomeDataSource; // … and creates all columns View.DataController.CreateAllItems; end; 此楼回复Re: --------------------------------------------------------------------------------====================================================================== 获得Group Footer合计行对应的记录 procedure TForm1.cxGrid1DBTableView1CustomDrawFooterCell( Sender: TcxGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxGridColumnHeaderViewInfo; var ADone: Boolean); var ALevel, ADataGroupIndex: Integer; AGridRecord, AGroupRecord: TcxCustomGridRecord; begin if AViewInfo is TcxGridRowFooterCellViewInfo and // Row footer (TcxGridDBColumn(AViewInfo.Column).DataBinding.FieldName = 'Area') then // Area column begin AGridRecord := TcxGridRowFooterCellViewInfo(AViewInfo).GridRecord; ALevel := TcxGridRowFooterCellViewInfo(AViewInfo).Container.GroupLevel; ADataGroupIndex := Sender.DataController.Groups.DataGroupIndexByRowIndex[AGridRecord.Index]; if ADataGroupIndex <> -1 then begin AGroupRecord := AGridRecord; while AGroupRecord.Level <> ALevel do AGroupRecord := AGroupRecord.ParentRecord; AViewInfo.Text := AGroupRecord.DisplayTexts[0]; end; end; end; =========================================================================== 访问过滤之后的记录 var I: Integer; begin Memo1.Lines.Clear; with cxGrid1DBTableView1.DataController do for I := 0 to FilteredRecordCount - 1 do Memo1.Lines.Add(DisplayTexts[FilteredRecordIndex[I], 0]); end; ============================================================================ 获得单元的Font cxGrid1DBTableView1.ViewInfo.RecordsViewInfo.Items[1].GetCellViewInfoByItem( cxGrid1DBTableView1Company).EditViewInfo.Font; ============================================================================ 根据Level名称找到Level对象 function GetLevelByName(AGrid: TcxGrid; ALevelName: string): TcxGridLevel; function LoopThroughLevels(ALevel: TcxGridLevel; ALevelName: string): TcxGridLevel; var I: Integer; begin Result := nil; for I := 0 to ALevel.Count - 1 do begin if ALevel[I].Name = ALevelName then begin Result := ALevel[I]; Exit; end; if ALevel[I].Count > 0 then begin Result := LoopThroughLevels(ALevel[I], ALevelName); if Result <> nil then Exit; end; end; end; var I: Integer; begin Result := nil; for I := 0 to AGrid.Levels.Count - 1 do begin if AGrid.Levels[I].Name = ALevelName then begin Result := AGrid.Levels[I]; Exit; end; if AGrid.Levels[I].Count > 0 then begin Result := LoopThroughLevels(AGrid.Levels[I], ALevelName); if Result <> nil then Exit; end; end; end; ============================================================================ 指定Filter Builder打开/保存过滤文件的默认路径 uses ..., cxFilterControlDialog; procedure TForm.GridView1FilterControlDialogShow( Sender: TObject); begin TfmFilterControlDialog(Sender).OpenDialog.InitialDir := 'D:\' end; ============================================================================ 保存/恢复带汇总行的布局
.StoreToIniFile('c:\Grid.ini', True, [gsoUseSummary]);
.RestoreFromIniFile(
,True,False {or True, optional},[gsoUseSummary]); ============================================================================ 取消过滤时移到第一行 uses cxCustomData; procedure TYour_Form.AViewDataControllerFilterChanged(Sender: TObject); var Filter: TcxDataFilterCriteria; begin with Sender as TcxDataFilterCriteria do if IsEmpty then DataController.FocusedRowIndex := 0; end; ============================================================================= 排序后移到第一行 可以设置DataController.Options.FocusTopRowAfterSorting := True,也可以使用如下的代码: uses cxCustomData; procedure TYour_Form.Your_ViewDataControllerSortingChanged(Sender: TObject); begin TcxCustomDataController(Sender).FocusedRowIndex := 0; end; ============================================================================== 判断当前行是否第一行或最后一行 可以使用DataController的IsBOF, IsEOF方法,或者:
.Controller.Controller.FocusedRow.IsFirst
.Controller.Controller.FocusedRow.IsLast ============================================================================== 根据指定值查找记录 DataController提供了好几个方法来得到指定值对应的RecordIndex 对于Bound View可以使用FindRecordIndexByKeyValue方法 =============================================================================== 编辑和显示Blob字段 该字段的Properties设置为BlobEdit,并将BlobPaintStyle 属性设为 bpsText =============================================================================== 得到可见行数
.ViewInfo.VisibleRecordCount =============================================================================== 保存后的行设置为当前行 const CM_SETFOCUSEDRECORD = WM_USER + 1002; type TForm1 = class(TForm) cxGrid1DBTableView1: TcxGridDBTableView; cxGrid1Level1: TcxGridLevel; cxGrid1: TcxGrid; dxMemData1: TdxMemData; dxMemData1Field1: TStringField; dxMemData1Field2: TIntegerField; DataSource1: TDataSource; cxGrid1DBTableView1RecId: TcxGridDBColumn; cxGrid1DBTableView1Field1: TcxGridDBColumn; cxGrid1DBTableView1Field2: TcxGridDBColumn; Timer1: TTimer; CheckBox1: TCheckBox; procedure Timer1Timer(Sender: TObject); procedure dxMemData1AfterPost(DataSet: TDataSet); procedure CheckBox1Click(Sender: TObject); private procedure CMSetFocusedRecord(var Msg: TMessage); message CM_SETFOCUSEDRECORD; public { Public declarations } end; var Form1: TForm1; FocusedIdx: Integer; implementation {$R *.dfm} procedure TForm1.Timer1Timer(Sender: TObject); begin dxMemData1.AppendRecord(['', IntToStr(Random(1000)), Random(1000)]); end; procedure TForm1.dxMemData1AfterPost(DataSet: TDataSet); begin PostMessage(Handle, CM_SETFOCUSEDRECORD, Integer(cxGrid1DBTableView1), MakeLParam(cxGrid1DBTableView1.Controller.FocusedRowIndex, cxGrid1DBTableView1.Controller.TopRowIndex)); end; procedure TForm1.CMSetFocusedRecord(var Msg: TMessage); begin TcxGridDBTableView(msg.WParam).Controller.FocusedRowIndex := Msg.LParamLo; TcxGridDBTableView(msg.WParam).Controller.TopRowIndex := Msg.LParamHi; end; procedure TForm1.CheckBox1Click(Sender: TObject); begin Timer1.Enabled := TCheckBox(Sender).Checked; end; end. ================================================================================= 删除记录并获得焦点 procedure TForm1.BtnDeleteClick(Sender: TObject); var FocusedRow, TopRow: Integer; View: TcxGridTableView; DataController: TcxGridDataController; begin View := cxGrid1.FocusedView as TcxGridTableView; DataController := View.DataController; // Remember the top row (the vertical scrollbar position) TopRow := View.Controller.TopRowIndex; // Remember the focused row(!) index FocusedRow := DataController.FocusedRowIndex; DataController.DeleteFocused; // After deletion the same row must be focused, // although it will correspond to a different data record DataController.FocusedRowIndex := FocusedRow; // Restore the top row View.Controller.TopRowIndex := TopRow; end; //=======================================================================================数据库中的财务表为: ID 收支类型 金额 其它属性 其中收支类型只有两种值:0 表示收入,1 表示支出 ;金额都是正数。 设置cxGrid的Footer 可以使得在显示时,列表的下方出现汇总行:“金额”的和 同样设置Default For Groups可以使得在用户拖动表头属性实现分组时,显示组内的汇总行:“金额”的和。 上面说的,用过cxGrid应该都会,下面就有这么一个问题 如果我想使汇总行的值变为如下的值应该怎样实现: 收支类型为0的金额的和 - 收支类型为1的金额的和 实现Footer的功能好办,因为它的值不会变,自己用循环写一个就完了,但是Default For Groups的功能就不好说了,因为它的值是根据用户拖动的属性计算的,而且还有可能是多层分组,想不出来了,所有到这来问 是不是要设置什么属性?或者cxGrid根本就没这个功能,那该用什么方法解决?希望哪位帮我解决,谢谢了先! 给你一个例子,可能对你有帮助, with tvOrders.DataController.Summary do begin BeginUpdate; try SummaryGroups.Clear; //The first summary group with SummaryGroups.Add do begin //Add proposed grouping column(s) TcxGridTableSummaryGroupItemLink(Links.Add).Column := tvOrdersCustomerID; //Add summary items with SummaryItems.Add as TcxGridDBTableSummaryItem do begin Column := tvOrdersPaymentAmount; Kind := skSum; Format := 'Amount Paid: $,0'; end; with SummaryItems.Add as TcxGridDBTableSummaryItem do begin Column := tvOrdersPaymentAmount; Kind := skCount; Format := 'Records: 0'; end; end; //The second summary group with SummaryGroups.Add do begin //Add proposed grouping column(s) TcxGridTableSummaryGroupItemLink(Links.Add).Column := tvOrdersProductID; //Add summary items with SummaryItems.Add as TcxGridDBTableSummaryItem do begin Column := tvOrdersQuantity; Kind := skSum; Position := spFooter; Format := 'TOTAL = 0'; end; with SummaryItems.Add as TcxGridDBTableSummaryItem do begin Column := tvOrdersPurchaseDate; Kind := skMin; Position := spFooter; end; end; finally EndUpdate; end; end; 2007-7-19 12:56:41 go on 订单号 商品名 单价 数量 金额001 aa 11.00 2 22.00001 bb 2.00 2 4.00001 cc 3.00 3 9.00----------------------合计 7 35.00002 ee 11.00 2 22.00002 bb 3.00 2 6.00002 cc 3.00 3 9.00----------------------合计 7 37.00总计14 72.00每个单号分一个小结,能实现吗?最后在底下实现总的合计
 

转载于:https://www.cnblogs.com/m0488/p/7402379.html

你可能感兴趣的文章
由Oracle 11g SYSAUX 和 SYSTEM 表空间回收引发的联想
查看>>
欲则不达
查看>>
盒子游戏
查看>>
Jmeter + Grafana搭建实时监控可视化
查看>>
uCGUI字符串显示过程分析和uCGUI字库的组建
查看>>
h5唤起app
查看>>
SQL Server 2008 /SQL Server 2008 R2 配置数据库邮件
查看>>
处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“Manag
查看>>
01: socket模块
查看>>
mysql触发器
查看>>
淌淌淌
查看>>
web页面实现指定区域打印功能
查看>>
使用PHP拆分中文字符串的方法(收藏) 小节
查看>>
win10每次开机都显示“你的硬件设置已更改,请重启电脑……”的解决办法
查看>>
VMware环境和Window环境进行网络连接的问题
查看>>
macOS10.12允许所有来源设置
查看>>
C++有关 const & 内敛 & 友元&静态成员那些事
查看>>
函数积累
查看>>
python搜索引擎(转)
查看>>
关于height,line-height导致的样式混乱的问题
查看>>