好久没有写笔记了,现在有点时间,来篇。

             happycyp  2007-7-19

cxGrid功能强大,适合做企业级的复杂查询。非常方便。

但是对其用法介绍的并不多,在此总结他人的使用经验和自己的一点小经验,供大家参考。

(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

查看评语&raquo;&raquo;&raquo;

2007-7-19 12:53:09    别人的,转载http://www.showding.cn/item/cxGrid__182526.aspx

最近在学习使用cxGrid,安装的版本是ExpressQuantumGrid   Suite   v5.10

我发现这个控件功能虽然强大,但是非常难用。

现在我手头就有几个问题还没解决:

1)主从模式下导出Excel中文会产生乱码,而且从表内容没有导出。

我不知道是不是因为我的字段名包括单引号的原因。

导出代码:ExportGrid4ToExcel(FileName,   cxGrid);

后面的版本:

cxgrid 导出数据USES
cxTLExportlink,//CXDBTREELIST导出文件引用单元
cxgridExportlink,//CXgrid导出文件引用单元
cxExportPivotGridLink;procedure CXGRIDToFile(VAR GOTGrid:TCXGRID;GOFILE:INTEGER);
BEGINcase gofile of0:dm.SaveDialog.Filter:='EXCEL文件|*.xls';1:dm.SaveDialog.Filter:='文本文件|*.TXT';2:dm.SaveDialog.Filter:='HTML文件|*.HTML';END;if dm.SaveDialog.Execute thenBEGINcase gofile of0:ExportGridToEXCEL(dm.SaveDialog.FileName,GOTGrid,TRUE,TRUE);1:ExportGridToTEXT(dm.SaveDialog.FileName,GOTGrid,TRUE,TRUE);2:ExportGridToHTML(dm.SaveDialog.FileName,GOTGrid,TRUE,TRUE);end;Application.MessageBox('文件已保存','系统提示',48);END;
END;
//CXDBTREELIST导出文件
procedure CXtreeToFile(VAR GOTree:TcxDBTreeList;GOFILE:INTEGER);//
begincase gofile of0:dm.SaveDialog.Filter:='EXCEL文件|*.xls';1:dm.SaveDialog.Filter:='文本文件|*.TXT';2:dm.SaveDialog.Filter:='HTML文件|*.HTML';END;if dm.SaveDialog.Execute thenBEGINcase gofile of0:cxExportTLToEXCEL(dm.SaveDialog.FileName,GOTree,TRUE,TRUE);1:cxExportTLToTEXT(dm.SaveDialog.FileName,GOTree,TRUE,TRUE);2:cxExportTLToHTML(dm.SaveDialog.FileName,GOTree,TRUE,TRUE);end;Application.MessageBox('文件已保存','系统提示',48);END;
end;
//交叉表导出文件
procedure cxPivotToFile(VAR GOPivot:TcxDBPivotGrid;GOFILE:INTEGER);
VAR FILEP:STRING;
begincase gofile of0:dm.SaveDialog.Filter:='EXCEL文件|*.xls';1:dm.SaveDialog.Filter:='文本文件|*.TXT';2:dm.SaveDialog.Filter:='HTML文件|*.HTML';END;if dm.SaveDialog.Execute thenBEGINcase gofile of0:cxExportPivotGridToExcel(pchar(dm.SaveDialog.FileName),GOPivot);1:cxExportPivotGridToText(pchar(dm.SaveDialog.FileName),GOPivot);2:cxExportPivotGridToHtml(pchar(dm.SaveDialog.FileName),GOPivot);end;Application.MessageBox('文件已保存','系统提示',48);END;
end;

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;

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

隐藏   "<No   data   to   display>"   字符串

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

来隐藏该文本。

uses   cxClasses,   cxGridStrs;

...

cxSetResourceString(@scxGridNoDataInfoText,   '');

//如果"<No   data   to   display>"   字符串已经显示,需要调用:

<View>.LayoutChanged;

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

删除应用过滤后的行

var

I:   Integer;

begin

with   <GridView>   do

for   I   :=   0   to   ViewData.RecordCount   -   1   do

begin

ViewData.Records[0].Focused   :=   True;

DataController.DataSet.Delete;

end;

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

根据单元的值设置样式

procedure   <aForm>.<aColumn>StylesGetContentStyle(

Sender:   TcxCustomGridTableView;   ARecord:   TcxCustomGridRecord;

AItem:   TcxCustomGridTableItem;   out   AStyle:   TcxStyle);

begin

if   ARecord.Values[AItem.Index]   =   aSomeValue   then

AStyle   :=   <aSomeStyle>;

end;

procedure   <aForm>.<aView>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   :=   <cxGrid>.CreateView(TcxGridDBBandedTableView);

TcxGridDBBandedTableView(AView).DataController.DataSource   :=   <DataSource>;

TcxGridDBBandedTableView(AView).Bands.Add;

with   TcxGridDBBandedTableView(AView).Bands.Add   do

begin

Visible   :=   False;

FixedKind   :=   fkLeft;

end;

TcxGridDBBandedTableView(AView).DataController.CreateAllItems;

<cxGridLevel>.GridView   :=   AView;

此楼回复Re:

--------------------------------------------------------------------------------

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

当底层数据集为空时显示一条空记录

procedure   <Form>.<cxGrid>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)   <aView>.Controller.EditingController.ShowEdit(<aColumn>);

2)   <aView>.Controller.EditingController.StartEditShowingTimer(<aColumn>);

3)   <aView>.Controller.EditingItem   :=   <aColumn>;

4)   <aColumn>.Editing   :=   True;

隐藏内置编辑控件

<aView>.Controller.EditingController.HideEdit(True);

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

移除一个分组列

<aColumn>.GroupIndex   :=   -1;

<aColumn>.Visible   :=   True;

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

保存修改到数据库

procedure   <aForm>.FormClose(Sender:   TObject;   var   Action:   TCloseAction);

begin

if   (<aGrid>.FocusedView   <>   nil)   and   (<aGrid>.FocusedView.DataController.EditState   <>   [])   then

<aGrid>.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

<GridView>.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;

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

保存/恢复带汇总行的布局

<TableView>.StoreToIniFile('c:\Grid.ini',   True,   [gsoUseSummary]);

<GridView>.RestoreFromIniFile(<inifilename>,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方法,或者:

<AView>.Controller.Controller.FocusedRow.IsFirst

<AView>.Controller.Controller.FocusedRow.IsLast

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

根据指定值查找记录

DataController提供了好几个方法来得到指定值对应的RecordIndex

对于Bound   View可以使用FindRecordIndexByKeyValue方法

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

编辑和显示Blob字段

该字段的Properties设置为BlobEdit,并将BlobPaintStyle   属性设为   bpsText

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

得到可见行数

<View>.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.00

001 bb 2.00 2 4.00

001 cc 3.00 3 9.00

----------------------合计 7 35.00

002 ee 11.00 2 22.00

002 bb 3.00 2 6.00

002 cc 3.00 3 9.00

----------------------合计 7 37.00

总计14 72.00

每个单号分一个小结,能实现吗?

最后在底下实现总的合计

回复人:dctony() ( ) 信誉:100 2007-1-12 21:48:23 得分:100

?

可以的,cxGrid的功能比你想象的还要强大。

1.你先放一个cxGrid,设置好View,设置View.DataController连接的DataSource

2.激活DataSource连接的DataSet,双击cxGrid,点击Retrieve Fields,取得所有的Column

3.设置View的OptionsView.Footer=True,OptionsView.GroupFooters=True,这是为了把分组小计和总计面板显示出来

4.将“订单号”字段拖到cxGrid上方的分组面板(GroupbyBox),将数据按“订单号”分组。这时你会发现单身所有的数据都缩起来了,如果想使所有的数据都展开,可以设置View.

DataController.Options.dcoGroupsAlwaysExpanded=True

5.设置分组小计:把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上的所有地方,左键或右键,你都会有意外收获。

ExpressQuantumGrid控件实在是太复杂,太庞大,最好的了解它的方法就是查帮助。

好久没有写笔记了,现在有点时间,来篇。

             happycyp  2007-7-19

cxGrid功能强大,适合做企业级的复杂查询。非常方便。

但是对其用法介绍的并不多,在此总结他人的使用经验和自己的一点小经验,供大家参考。

(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

查看评语&raquo;&raquo;&raquo;

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;

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

隐藏   "<No   data   to   display>"   字符串

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

来隐藏该文本。

uses   cxClasses,   cxGridStrs;

...

cxSetResourceString(@scxGridNoDataInfoText,   '');

//如果"<No   data   to   display>"   字符串已经显示,需要调用:

<View>.LayoutChanged;

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

删除应用过滤后的行

var

I:   Integer;

begin

with   <GridView>   do

for   I   :=   0   to   ViewData.RecordCount   -   1   do

begin

ViewData.Records[0].Focused   :=   True;

DataController.DataSet.Delete;

end;

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

根据单元的值设置样式

procedure   <aForm>.<aColumn>StylesGetContentStyle(

Sender:   TcxCustomGridTableView;   ARecord:   TcxCustomGridRecord;

AItem:   TcxCustomGridTableItem;   out   AStyle:   TcxStyle);

begin

if   ARecord.Values[AItem.Index]   =   aSomeValue   then

AStyle   :=   <aSomeStyle>;

end;

procedure   <aForm>.<aView>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   :=   <cxGrid>.CreateView(TcxGridDBBandedTableView);

TcxGridDBBandedTableView(AView).DataController.DataSource   :=   <DataSource>;

TcxGridDBBandedTableView(AView).Bands.Add;

with   TcxGridDBBandedTableView(AView).Bands.Add   do

begin

Visible   :=   False;

FixedKind   :=   fkLeft;

end;

TcxGridDBBandedTableView(AView).DataController.CreateAllItems;

<cxGridLevel>.GridView   :=   AView;

此楼回复Re:

--------------------------------------------------------------------------------

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

当底层数据集为空时显示一条空记录

procedure   <Form>.<cxGrid>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)   <aView>.Controller.EditingController.ShowEdit(<aColumn>);

2)   <aView>.Controller.EditingController.StartEditShowingTimer(<aColumn>);

3)   <aView>.Controller.EditingItem   :=   <aColumn>;

4)   <aColumn>.Editing   :=   True;

隐藏内置编辑控件

<aView>.Controller.EditingController.HideEdit(True);

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

移除一个分组列

<aColumn>.GroupIndex   :=   -1;

<aColumn>.Visible   :=   True;

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

保存修改到数据库

procedure   <aForm>.FormClose(Sender:   TObject;   var   Action:   TCloseAction);

begin

if   (<aGrid>.FocusedView   <>   nil)   and   (<aGrid>.FocusedView.DataController.EditState   <>   [])   then

<aGrid>.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

<GridView>.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;

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

保存/恢复带汇总行的布局

<TableView>.StoreToIniFile('c:\Grid.ini',   True,   [gsoUseSummary]);

<GridView>.RestoreFromIniFile(<inifilename>,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方法,或者:

<AView>.Controller.Controller.FocusedRow.IsFirst

<AView>.Controller.Controller.FocusedRow.IsLast

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

根据指定值查找记录

DataController提供了好几个方法来得到指定值对应的RecordIndex

对于Bound   View可以使用FindRecordIndexByKeyValue方法

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

编辑和显示Blob字段

该字段的Properties设置为BlobEdit,并将BlobPaintStyle   属性设为   bpsText

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

得到可见行数

<View>.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.00

001 bb 2.00 2 4.00

001 cc 3.00 3 9.00

----------------------合计 7 35.00

002 ee 11.00 2 22.00

002 bb 3.00 2 6.00

002 cc 3.00 3 9.00

----------------------合计 7 37.00

总计14 72.00

每个单号分一个小结,能实现吗?

最后在底下实现总的合计

回复人:dctony() ( ) 信誉:100 2007-1-12 21:48:23 得分:100

?

可以的,cxGrid的功能比你想象的还要强大。

1.你先放一个cxGrid,设置好View,设置View.DataController连接的DataSource

2.激活DataSource连接的DataSet,双击cxGrid,点击Retrieve Fields,取得所有的Column

3.设置View的OptionsView.Footer=True,OptionsView.GroupFooters=True,这是为了把分组小计和总计面板显示出来

4.将“订单号”字段拖到cxGrid上方的分组面板(GroupbyBox),将数据按“订单号”分组。这时你会发现单身所有的数据都缩起来了,如果想使所有的数据都展开,可以设置View.

DataController.Options.dcoGroupsAlwaysExpanded=True

5.设置分组小计:把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上的所有地方,左键或右键,你都会有意外收获。

ExpressQuantumGrid控件实在是太复杂,太庞大,最好的了解它的方法就是查帮助。

转载于:https://www.cnblogs.com/usegear/archive/2012/09/13/2683305.html

cxGrid功能_用于备查【转】相关推荐

  1. 熔池 沉积_用于3D打印的AI(第3部分):异常熔池分类的纠缠变分自动编码器

    熔池 沉积 This article is part 3 of the AI for 3-D printing series. Read part 1 and part 2. 本文是3-D打印AI系列 ...

  2. 磁珠 符号_贴片磁珠功能_贴片磁珠应用

    磁珠专用于抑制信号线.电源线上的高频噪声和尖峰干扰,还具有吸收静电脉冲的能力.磁珠是用来吸收超高频信号,像一些RF电路,PLL,振荡电路,含超高频存储器电路(DDRSDRAM,RAMBUS等)都需要在 ...

  3. 探花交友_第1章_项目介绍以及实现登录功能_第1节_功能介绍

    探花交友_第1章_项目介绍以及实现登录功能_第1节_功能介绍 文章目录 探花交友_第1章_项目介绍以及实现登录功能_第1节_功能介绍 1.功能介绍 1.1.功能列表 1.2.注册登录 1.3.交友 1 ...

  4. SAP MM里的ERS功能不适用于供应商寄售采购模式

    SAP MM里的ERS功能不适用于供应商寄售采购模式 今天收到了一个做零售行业项目的SAP同行的问题,客户问她是否可以在供应商寄售采购流程里启用SAP的ERS功能.我甚为吃惊,感觉这个SAP客户的问题 ...

  5. java获取method,2.5 反射——Class对象功能_获取Method

    >[info] 反射--Class对象功能_获取Method * Method:方法对象 * 执行方法: * Object invoke(Object obj, Object... args) ...

  6. tda7294参数引脚功能_电容在电路中的几种功能

    电容在电路中非常常见,不同的电容,放置的位置不同,其功能也会不同,今天就给大家介绍一下电容在电路中的几种功能. 1. 去耦功能 电容可以用于去耦.这种算是电容最为常见的功能了,由于1/wc的效应存在, ...

  7. Windows Server 2008之旅??Windows Server Backup功能_闲云野鹤?精神家园_百度空间

    为什么80%的码农都做不了架构师?>>>    Windows Server 2008之旅??Windows Server Backup功能 2008-08-17 10:43 备份无 ...

  8. iPhone卫星功能仅用于紧急通信;韩国通过立法禁止苹果、谷歌垄断支付系统;Linux 5.14 版本发布|极客头条

    一分钟速览新闻点! 小米集团加入开源专利社区 OIN 饿了么:延长扬州会员一个月的权益 阿里云教育推出钉钉课后服务系统 华为 P50 Pro 推送鸿蒙更新 淘宝更换新的 Slogan 为"淘 ...

  9. V90 PN 伺服驱动器的一键自动优化功能_方法示例

    V90 PN 伺服驱动器的一键自动优化功能_方法示例 首先,了解一下伺服系统的组成,如下图所示,电流环.速度环和位置环 重点: 伺服系统的调节要结合实际的电机机械负载. 对于V90伺服驱动器,支持手动 ...

最新文章

  1. 由一个Quiz想到的
  2. 《Java并发编程入门与高并发面试》or 《Java并发编程与高并发解决方案》笔记
  3. php 三元运算符 为空,PHP中三元运算符和Null合并运算符的简单比较
  4. java如何将string转换成date_java如何将string类型转为date类型?Java的转型方法
  5. HDOJ-3790-最短路径问题 解题报告
  6. 面向对象(方法的形式参数)
  7. SQL 使用总结四(关于索引)
  8. 使用CALayer设置图像边框
  9. C++简介(3)--引用和指针
  10. 去掉Eclipse打开后定期弹出Usage Data Upload对话框
  11. 关于H264相关的EBSP,RBSP,SODP的说明
  12. 1. javascript 引擎Rhino源代码分析 简介
  13. appium IOS 报错 [iProxy] recv failed: Operation not permitted
  14. ECharts学习--雷达图
  15. 【VUE2开发20221004】-day1.1
  16. 图片情感识别/分类/分析 概述
  17. 我虽买不起99朵玫瑰花送你,但它可以——(看完还不肯当我女朋友?)
  18. Jqurey总结归纳
  19. HTML5基础教程(21)Audio(音频)
  20. 计算机二级C语言题型分值占比+考试要求+考试内容

热门文章

  1. sublime搭建python开发环境_使用sublime搭建python开发环境
  2. SRC漏洞挖掘之偏门资产收集篇
  3. 配置Nginx来支持php
  4. OpenCV图像处理基础操作汇总
  5. 机器学习入门02-朴素贝叶斯原理和java实现
  6. Nutch+Hadoop集群搭建
  7. Python提取数字图片特征向量
  8. dojo中的dojo/dom-style
  9. Kerberos认证代码分析Can't get Kerberos realm
  10. Tomcat源码解析一:下载源码与导入eclipse