delphi CxGrid用法总结(63问)
Posted cipherlab
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了delphi CxGrid用法总结(63问)相关的知识,希望对你有一定的参考价值。
转:https://www.cnblogs.com/regest/p/7114815.html
1. 去掉cxGrid中台头的Box
解决:在tableview1的optionsview的groupbybox=false;
*****************************************************************************
2.统计功能
解决:(1) tableview
tableview1的optionsviewfooter=ture
然后在cxGRid1的customize..中的summary 的footer.add需要合计的列kind= skSum
在Footer的第一列显示[合计:]
加一个Summary项,Column设为Grid的第一列,Kind设为skNone
在该Summary项的OnGetText事件中,输入:
procedure TFormExpense.tvExpenseTcxGridDBDataControllerTcxDataSummaryFooterSummaryItems2GetText(
Sender: TcxDataSummaryItem; const AValue: Variant; AIsFooter: Boolean;
var AText: String);
begin
AText := ‘合计:‘;
end;
(2) 按条件汇总:
在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;
OptionView中属性GroupFooters设为gfAlwaysVisible并设置需要求和的列,在summary.default for Groups 下add加入需要合计的字段,column下显示fieldname 为统计字段,format为格式,kind为统计方法,position 为位子 spfooter 在分组的下面,spgroup 在分组的上面
或用cxGridPopupMenu1,在运行時可对任意数字类型列求和,方法是只需设置cxGridPopupMenu1的属性Grid为cxGrid1DBTableView1的cxGrid,
*****************************************************************************
3.去掉cxgrid 中的过滤下拉箭头
解决: 选择tableview1.optionscustomize.columnfiltering=fasle;
****************************************************************************
4.让“Drag a column here to group by that column”不显示
解决:在cxGrid1DBTableView1->optionsview->groupbybox:=false即可
****************************************************************************
5.GroupPanel上面的英文[Drag a column header to group by that column]怎么可以改成中文
解决:最简单的方法是 TcxGridTableView.OnCustomDrawPartBackground,
也可用 OnCustomDrawGroupCell:
procedure TForm1.cxGrid1DBTableView1CustomDrawPartBackground(
Sender: TcxGridTableView; ACanvas: TcxCanvas;
AViewInfo: TcxCustomGridCellViewInfo; var ADone: Boolean);
begin
AViewInfo.Text:=‘动态设置 GroupBox 的显示内容‘;
ACanvas.FillRect(AViewInfo.Bounds);
end;
注:改成中文后将字段拖上去中文还是会显示,最好是设置空值
****************************************************************************
6.如何实现如下功能:
+财务部
+原材料仓库
+成品库
+冲压车间
+软件开发部
这个是部门的名称,点击加号就可以将本部门的人员情况显示出来。
解决:其实这是一个主从表关系,1:填好主表的keyfieldnames
2:填好从表的keyfieldnames
3:填好从表的 detaikeyfieldNames与masterkeyfieldnames
4: 从表的数据源一定要按与主表关联的字段排序
注:其它地方设置了主从表结构那样就显示不出来,比如设置了从表的Table或者Query的mastersource和
masterfield就会不能显示数据!如果是两个cxGrid的主从关系,这样设置就很OK了。
****************************************************************************
7.类似PageControl显示
解决:增加一个Level,将cxGrid1->RootLevelOptions->DetailTabsPosition设为dtpTop,然后相应的设置cxGrid1Level1,和cxGrid1Level2的Caption值。
****************************************************************************
8.如何设定左边几列,不能滚动
解决:使用DB Banded Table才可以实现,
在cxGrid1DBBandedTableView里建立Band0,Band1
Band0的Fixed=tfLeft
Band1的Fixed=tfnone
设置要锁定的字段的BandIndex=0,其它为1,就OK了。
*******************************************************************************
9. 怎样实现如EXCEL一样的,当前格=G14+G15+G16 这样的功能
解决: 举一个简单的例子:label1.Caption := cxGrid1DBTableView1.DataController.Values[2,
3]+cxGrid1DBTableView2.DataController.Values[1, 1]+cxGrid1DBTableView3.DataController.Values[1, 1];
所以不同cxGrid1DBTableView中的数据都可以给当前格,这样就做到了EXCEL中的当前格=G14+G15+G16 类似的功能。
****************************************************************************
10. 鼠标右击cxGrid1DBBandedTableView1菜单里的Edit Layout什么用,怎么使用?
解决:可以拖动字段,并列的可以拖成有层次感(一层层), 拖动时会显示箭头的,就是说可以拖一个字段放
****************************************************************************
11.怎样将cxGrid里的数据导入到EXCEL,html,XML和TEXT
解决:uses
cxExportGrid4Link; ( cxExportGrid6Link)
procedure TForm1.Button1Click(Sender: TObject);
begin
ExportGrid4ToEXCEL(‘d:/wang.xsl‘,cxGrid1,True,True);
ExportGrid4ToTEXT(‘d:/wang.txt‘,cxGrid1,True,True);
ExportGrid4ToXML(‘d:/wang.xml‘,cxGrid1,True,True);
ExportGrid4ToHTML(‘d:/wang.html‘,cxGrid1,True,True);
end;
****************************************************************************
12. 如何使满足条件的数据显示不同的颜色?
解决:
var
AYellowStyle: TcxStyle;
procedure TForm1.FormCreate(Sender: TObject);
begin
//行颜色
AYellowStyle := TcxStyle.Create(Self);
AYellowStyle.Color := $0080FFFF;
AYellowStyle.TextColor := clMaroon;
end;
procedure TForm1.cxGrid1DBBandedTableView1StylesGetContentStyle(
Sender: TcxCustomGridTableView; ARecord: TcxCustomGridRecord;
AItem: TcxCustomGridTableItem; out AStyle: TcxStyle);
begin
if ARecord.Values[cxGrid1DBBandedTableView1Lengthcm.Index] < 81 then
AStyle := AYellowStyle;
end;
这里cxGrid1DBBandedTableView1Lengthcm.Index小于81时就显示黄色
****************************************************************************
13. 如何从外边的TXT文件导入到cxGrid?
解决:
procedure CustomizeColumns;
procedure LoadData;
procedure TForm1.CustomizeColumns;
const
cDistance = 1;
cRadius = 5;
cPeriod = 4;
cPstring = 0;
var
I: Integer;
begin
DecimalSeparator := ‘.‘;
with cxGrid1TableView2 do
for I := 0 to ColumnCount - 1 do
if I in [cDistance, cRadius] then
Columns[I].DataBinding.ValueTypeClass := TcxIntegerValueType//1,5列为Integer
else
if I in [cPstring,cPeriod] then
Columns[I].DataBinding.ValueTypeClass := TcxStringValueType//0,4列为String
else
Columns[I].DataBinding.ValueTypeClass := TcxFloatValueType;//其他为Float
end;
procedure TForm1.LoadData;
const
AFileName = ‘资产负债表.txt‘;
AHeaderLineCount = 2;
var
ARecords, AValues: TStringList;
I: Integer;
procedure InitRecord(const Str: string);
var
J: Integer;
V: Variant;
begin
AValues.CommaText := Str;
for J := 0 to AValues.Count - 1 do
if AValues.Strings[J] <> ‘-‘ then
begin
V := AValues.Strings[J];
if not VarIsNull(V) then
cxGrid1TableView2.DataController.Values[I, J] := V;
end;
end;
begin
if not FileExists(AFileName) then
raise Exception.Create(‘Data file not found‘);
ARecords := TStringList.Create;
AValues := TStringList.Create;
with ARecords do
try
LoadFromFile(AFileName);
cxGrid1TableView2.BeginUpdate;
cxGrid1TableView2.DataController.RecordCount := Count - AHeaderLineCount;
for I := 0 to Count - (AHeaderLineCount + 1) do
InitRecord(Strings[I + AHeaderLineCount]);
finally
cxGrid1TableView2.EndUpdate;
ARecords.Free;
AValues.Free;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
CustomizeColumns;
LoadData_Zcfz;
end;
****************************************************************************
14 如何改变列的颜色?
解决:
var
AFirstColumnStyle: TcxStyle;
procedure TForm1.FormCreate(Sender: TObject);
begin
//列颜色
AFirstColumnStyle := TcxStyle.Create(Self);
AFirstColumnStyle.Color := clAqua;
AFirstColumnStyle.TextColor := clBlue;
cxGrid1TableView1.Columns[1].Styles.Content := AFirstColumnStyle;
end;
****************************************************************************
15 Set as default的用法?
解决:Set as default的用法是为了解决设置参数的方便而做的,比如:
连好数据库以后,更改cxGrid1DBBandedTableView1->OptionsCustomize-> ColumnFiltering 设为False。(这个设置可以将字段名的下拉单给去掉)更改cxGrid1DBBandedTableView1->OptionsView- >Navigator 设置为True。然后右击cxGrid1DBBandedTableView1,在弹出的菜单栏里面点击Set as default。
OK,下次你再产生一个新的cxGrid1DBBandedTableView1时这些设置和刚才的一样了。如果需要设置的参数很多的时候,这个Set as default很有用!
****************************************************************************
16. 怎样使鼠标移动时,相应的单元里的文字变色?
解决:
var
FTrackItem: TcxCustomGridTableItem;
FTrackRec: TcxCustomGridRecord;
procedure TForm1.cxGrid1DBTableView1CustomDrawCell(
Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
begin
if (AViewInfo.GridRecord = FTrackRec) and (AViewInfo.Item = FTrackItem) then
begin
ACanvas.Font.Color := clred; //红色字体
ACanvas.Font.Style := [fsUnderline];//带下划线
end;
end;
procedure TForm1.cxGrid1DBTableView1MouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);
var
AHitTest: TcxCustomGridHitTest;
ATrackItem: TcxCustomGridTableItem;
ATrackRec: TcxCustomGridRecord;
begin
ATrackItem := FTrackItem;
ATrackRec := FTrackRec;
AHitTest := (Sender as TcxGridSite).GridView.ViewInfo.GetHitTest(X, Y);
if AHitTest is TcxGridRecordCellHitTest then
begin
FTrackItem := TcxGridRecordCellHitTest(AHitTest).Item;
FTrackRec := TcxGridRecordCellHitTest(AHitTest).GridRecord;
end
else
begin
FTrackItem := nil;
FTrackRec := nil;
end;
if (ATrackItem <> FTrackItem) or (ATrackRec <> FTrackRec) then
begin
// Invalidate old cell
if ATrackRec <> nil then
ATrackRec.Invalidate(ATrackItem);
// Invalidate new cell
if FTrackRec <> nil then
FTrackRec.Invalidate(FTrackItem);
end;
end;
****************************************************************************
zj注:17-27转载自http://blog.csdn.net/shuaihj/article/details/6131011
17. 怎样设计多表头的cxGrid?
解决:cxGrid可以解决如下的表头:
---------------------------------
| 说明1 | 说明2 |
---------------------------------
| 字段1 | 字段2 | 字段3 | 字段4 |
| 字段5 | 字段6 |
| 字段7 | 字段8 | 字段9 |
实现这个很简单,你可以直接在上面拖动字段名,拖动时会显示箭头的,放入你想显示的位置就OK了。或者在鼠标右击cxGrid1DBBandedTableView1菜单里的Edit Layout里也可以拖放。
但是cxGrid不能实现如下的多表头形式:
---------------------------------
| 说明1 | 说明2 |
---------------------------------
| 说明3 | 说明4 | 说明5 | 说明6 |
| 字段1 | 字段2 |
| 字段3 | 字段4 | 字段5 |
不知道有谁能实现这样的多表头?
****************************************************************************
18. 在主从表结构时,当点开“+”时怎样将焦点聚在相应主表的记录上?
解决:
var
HitTest: TcxCustomGridHitTest;
procedure TColumnsShareDemoMainForm.tvProjectsMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
// Note that the Sender parameter is a Site
HitTest := (Sender as TcxGridSite).GridView.ViewInfo.GetHitTest(X, Y);
// The point belongs to the [+]/[-] button area
if HitTest is TcxGridExpandButtonHitTest then
// Move focus to the record
TcxGridExpandButtonHitTest(HitTest).GridRecord.Focused := True;
end;
****************************************************************************
19 CXGrid4如何展开全部节点
解决:GridDBTableView1.DataController.Groups.FullExpand;
****************************************************************************
20. cxGrid如何动态创建Items的Editor的项?
解决:cxGrid的列有一个属性,它的编辑框可以指定combobox,spinedit等.在设计时,可以为
combobox的items添加项目.请问是否可以动态创建?(run-time时由程序加入)
var
A:TDataSource:
B:TcxlookupcomboboxProperties;
begin
A:=TDataSource.create(self);
B:=tcxlookupcomboboxproperties.create(self);
A.Dataset:=Dic_ry_xb;//此处指定数据源。
b.listdource:=a;//此处指明字段的listsource属性。
b.keyfieldnames:=‘a‘; //此处指明字段的关键字段
b.listfieldnames:=‘b‘; //此处指明字段的返回值。
b.listcolumns.items[0].caption:=‘x; //此处默认是会建立一个字段,但是显示的表头是name,所以此处让它显示为自己想要的中午显示。
cxGrid1DBTableView1c1_sex_code.Properties:=b; //此处指明是那个字段。
end; //这个是初始化的代码
****************************************************************************
21. 拷贝文件时有进度显示
解决:
procedure TForm1.mycopyfile(sourcef,targetf:string);
var
FromF, ToF: file;
NumRead, NumWritten: Integer;
Buf: array[1..2048] of Char;
n:integer;
begin
AssignFile(FromF, sourcef);
Reset(FromF, 1); { Record size = 1 }
AssignFile(ToF,targetf); { Open output file }
Rewrite(ToF, 1); { Record size = 1 }
n:=0;
repeat
BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
form1.label1.caption:=IntToStr(sizeof(buf)*n*100 div FileSize(FromF))+‘100%‘;
application.ProcessMessages;
//显示进度
BlockWrite(ToF, Buf, NumRead, NumWritten);
inc(n);
until (NumRead = 0) or (NumWritten <> NumRead);
form1.Label1.Caption:=‘100%‘;
CloseFile(FromF);
CloseFile(ToF);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
mycopyfile(‘e:/components/tv2k-w2k.zip‘,‘c:/a.zip‘);
end;
****************************************************************************
22. cxGrid 设置斑马线
解决:
在TcxGridDBBandedTableView.Styles属性中有 ContentEven(奇数行风格) ContentOdd (偶数行风格) ,设定一下风格就好了。
****************************************************************************
23 根据记录内容更改字体颜色
解决:
参考范例CustomDrawTableViewDemo,
主要在TcxGridDBBandedTableView.OnCustomDrawCell事件中实现。
如下代码:
if (Pos(‘-‘,AViewInfo.GridRecord.DisplayTexts[colOrderProductCount.Index]) > 0) then
begin //标识负数记录
//ACanvas.Canvas.Brush.Color:= clMoneyGreen;
ACanvas.Canvas.Font.Color:= clRed;//clActiveCaption
end;
其中colOrderProductCount是“产品订数”列。
还要有一步就是要刷新显示
TcxGridDBBandedTableView.LayoutChanged();
//tvCars.LayoutChanged(False);
TcxGridDBBandedTableView.Painter.Invalidate;
****************************************************************************
24 用代码展开/收缩主从结构
解决:
Self.tvDepartment.ViewData.Expand(True);
Self.tvDepartment.ViewData.Collaspe(True);
注:tvDepartment为主表对应的TableView
****************************************************************************
25 在内置右键菜单的后面增加菜单项
解决:
首先应在Form上加一个cxGridPopupMenu控件 以启用右键菜单
UseBuildInPopupMenus设为True
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;
****************************************************************************
26 根据某列的值设定其它列的可编辑性
解决:
procedure TFormUser.tvUserEditing(Sender: TcxCustomGridTableView;
AItem: TcxCustomGridTableItem; var AAllow: Boolean);
begin
//如果第三列值为True,则第4列不能修改
if (tvUser.Controller.FocusedRecord.Values[2] = True) and (AItem.Index = 4) then
AAllow := False
else
AAllow := True;
end;
****************************************************************************
27 保存/恢复Grid布局
解决:
网格左上角的自定义布局按钮:
TableView-?OptionsCustiomize?ColumnsQuickCustomization true;
//恢复布局
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); //保存为布局文件
实例:
IniFileName: string;
procedure TMainFM.FormCreate(Sender: TObject); //窗体创建时读取布局
var i: Integer;
begin
qyHed.Open;
IniFileName := ExtractFilePath(Application.ExeName) + ‘/Layout/‘ + cxGrd.Owner.ClassName + cxGrd.Name + ‘.ini‘;
if FileExists(IniFileName) then
Self.cxTbv.RestoreFromIniFile(IniFileName) //从布局文件中恢复
else
begin
Self.cxTbv.BeginUpdate;
for i := 0 to Self.cxTbv.ItemCount - 1 do
Self.cxTbv.Items[i].ApplyBestFit; //调整为最佳宽度
Self.cxTbv.EndUpdate;
end;
end;
procedure TMainFM.NSaveGrdClick(Sender: TObject); //保存布局文件
begin
try
IniFileName := ExtractFilePath(Application.ExeName) + ‘/Layout/‘ + cxGrd.Owner.ClassName + cxGrd.Name + ‘.ini‘;
if not DirectoryExists(ExtractFileDir(IniFileName)) then
CreateDir(ExtractFileDir(IniFileName));
Self.cxTbv.StoreToIniFile(IniFileName);
except
end;
end;
****************************************************************************
28保存/恢复带汇总行的布局解决:
<TableView>.StoreToIniFile(‘c:/Grid.ini‘, True, [gsoUseSummary]);
<GridView>.RestoreFromIniFile(<inifilename>,True,False{or True,optional},[gsoUseSummary]);
zj:本条与50条重复
****************************************************************************
(以下原博主转载自http://hi.baidu.com/jangill/blog/item/2cf3c782f82f0798f703a67f.html)
****************************************************************************
28 在主从TableView中根据主TableView得到对应的从TableView
解决:
var
ADetailDC: TcxGridDataController;
AView: TcxCustomGridTableView;
begin
with cxGrid1DBTableView1.DataController do
ADetailDC := TcxGridDataController(GetDetailDataController(FocusedRecordIndex, 0));
AView := ADetailDC.GridView;
end;
==============================================================================
29 定位在第一行并显示内置编辑器
cxDBVerticalGrid1.FocusedRow := cxDBVerticalGrid1.Rows[0];
cxDBVerticalGrid1.ShowEdit;
==============================================================================
30 隐藏 "<No data to display>" 字符串
该文本存储在scxGridNoDataInfoText资源字符串,可以将该资源字符串的内容设为空
来隐藏该文本。
uses cxClasses, cxGridStrs;
...
cxSetResourceString(@scxGridNoDataInfoText, ‘‘);
//如果"<No data to display>" 字符串已经显示,需要调用:
<View>.LayoutChanged;
============================================================
31 删除应用过滤后的行
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;
=============================================================
32 根据单元的值设置样式
解决:
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];
****************************************************************************
33 动态生成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;
end;
****************************************************************************
34 当底层数据集为空时显示一条空记录
解决:
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;
****************************************************************************
35 在当前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得到底层数据集后,再用数据集的方法来操作数据。
****************************************************************************
36 激活内置编辑控件
解决:
1) <aView>.Controller.EditingController.ShowEdit(<aColumn>);
2) <aView>.Controller.EditingController.StartEditShowingTimer(<aColumn>);
3) <aView>.Controller.EditingItem := <aColumn>;
4) <aColumn>.Editing := True;
****************************************************************************
37 隐藏内置编辑控件
解决:
<aView>.Controller.EditingController.HideEdit(True);
****************************************************************************
38 移除一个分组列
解决:
<aColumn>.GroupIndex := -1;
<aColumn>.Visible := True;
****************************************************************************
39 保存修改到数据库
解决:
procedure <aForm>.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if (<aGrid>.FocusedView <> nil)
and (<aGrid>.FocusedView.DataController.EditState <> []) then
<aGrid>.FocusedView.DataController.Post;
end;
****************************************************************************
40 设置内置右键菜单
解决:
内置右键菜单包括二个菜单: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;
****************************************************************************
41 得到选中记录的值
解决:
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;
****************************************************************************
42 在GridMode禁用内置的右键Footer菜单
解决:
uses cxGridStdPopupMenu;
procedure cxGridPopupMenuOnPopup(...)
begin
if (ASenderMenu is TcxGridStdFooterMenu) and
<GridView>.DataController.DataModeController.GridMode then
AllowPopup := False;
end;
****************************************************************************
43 主从表任何时候只能展开一个组
解决:
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;
****************************************************************************
44 动态创建层次(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;
****************************************************************************
45 获得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;
****************************************************************************
46 访问过滤之后的记录
解决:
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;
****************************************************************************
47 获得单元的Font
解决:
cxGrid1DBTableView1.ViewInfo.RecordsViewInfo.Items[1].GetCellViewInfoByItem(
cxGrid1DBTableView1Company).EditViewInfo.Font;
****************************************************************************
48 根据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;
****************************************************************************
49 指定Filter Builder打开/保存过滤文件的默认路径
解决:
uses
..., cxFilterControlDialog;
procedure TForm.GridView1FilterControlDialogShow(
Sender: TObject);
begin
TfmFilterControlDialog(Sender).OpenDialog.InitialDir := ‘D:/‘
end;
****************************************************************************
50 保存/恢复带汇总行的布局
<TableView>.StoreToIniFile(‘c:Grid.ini‘, True, [gsoUseSummary]);
<GridView>.RestoreFromIniFile(<inifilename>,True,False {or True, optional},[gsoUseSummary]);
****************************************************************************
51 取消过滤时移到第一行
解决:
uses
cxCustomData;
procedure TYour_Form.AViewDataControllerFilterChanged(Sender: TObject);
var
Filter: TcxDataFilterCriteria;
begin
with Sender as TcxDataFilterCriteria do
if IsEmpty then
DataController.FocusedRowIndex := 0;
end;
****************************************************************************
52 排序后移到第一行
解决:
可以设置DataController.Options.FocusTopRowAfterSorting := True,也可以使用如下的代码:
uses
cxCustomData;
procedure TYour_Form.Your_ViewDataControllerSortingChanged(Sender: TObject);
begin
TcxCustomDataController(Sender).FocusedRowIndex := 0;
end;
****************************************************************************
53 判断当前行是否第一行或最后一行
解决:
可以使用DataController的IsBOF, IsEOF方法,或者:
<AView>.Controller.Controller.FocusedRow.IsFirst
<AView>.Controller.Controller.FocusedRow.IsLast
****************************************************************************
54 根据指定值查找记录
解决:
DataController提供了好几个方法来得到指定值对应的RecordIndex
对于Bound View可以使用FindRecordIndexByKeyValue方法
****************************************************************************
55 编辑和显示Blob字段
解决:
该字段的Properties设置为BlobEdit,并将BlobPaintStyle 属性设为 bpsText
****************************************************************************
56 得到可见行数
解决:
<View>.ViewInfo.VisibleRecordCount
****************************************************************************
57 保存后的行设置为当前行
解决:
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.
****************************************************************************
58 删除记录并获得焦点
解决:
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;
****************************************************************************
59 cxGrid的 TableView 数据排序与对应的数据集同步
解决:
COPYRIGHT BY cnCharles, ALL RIGHTS RESERVED.
delphi群: 16497064, blog: http://hi.baidu.com/cnCharles
//描述: cxGrid的 TableView 数据排序与对应的数据集同步, 该方法主要用于打印时
// 的排序与所见到的排序保持一致;
//参数: @tv: 排序的cxGridTableView
//说明: @tv: 对应的数据集只支持 ADOQuery与 ClientDataSet;
procedure cxGridSortSyncToDataSet(tv: TcxGridDBTableView); overload;
//描述: 功能同上, 实现代码一样, 如果有更改就同步更改
procedure cxGridSortSyncToDataSet(tv: TcxGridDBBandedTableView); overload;
procedure cxGridSortSyncToDataSet(tv: TcxGridDBTableView);
const
SortArray: array[soAscending..soDescending] of string = (’ASC’, ’DESC’);
var
AscFields, DescFields, S, SortOrder: string;
IndexPrint: string;
I: integer;
Index: integer;
cds: TClientDataSet;
begin
S := ’’;
AscFields := ’’;
DescFields := ’’;
if tv.SortedItemCount = 0 then
Exit;
if tv.DataController.DataSource.DataSet is TADOQuery then begin
for I := 0 to tv.SortedItemCount - 1 do begin
SortOrder := SortArray[tv.SortedItems[I].SortOrder];
if S <> ’’ then
S := S + ’, ’;
Index := tv.SortedItems[I].Index;
S := S + tv.Columns[Index].DataBinding.Field.FieldName + ’ ’ + SortOrder;
end;
(tv.DataController.DataSource.DataSet as TADOQuery).Sort := S;
end else if (tv.DataController.DataSource.DataSet is TClientDataSet) then begin
Cds := tv.DataController.DataSource.DataSet as TClientDataSet;
for I := 0 to tv.SortedItemCount - 1 do begin
Index := tv.SortedItems[I].Index;
S := tv.Columns[Index].DataBinding.Field.FieldName +’;’;
AscFields := AscFields + S;
if tv.SortedItems[I].SortOrder = soDescending then
DescFields := DescFields + S;
end;
if AscFields <> ’’ then
Delete(AscFields, Length(AscFields), 1); //删除 ;
if DescFields <> ’’ then
Delete(DescFields, Length(DescFields), 1);
IndexPrint := TimeToStr(Now());
Cds.IndexDefs.Clear;
IndexPrint := TimeToStr(Now());
cds.AddIndex(IndexPrint, AscFields, [], DescFields);
cds.IndexName := IndexPrint;
end;
end;
****************************************************************************
60 cxGRID怎么遍历已经选择的单元格
解决:
n := cxGrid1DBTableView1.DataController.GetSelectedCount;
for i:=0 to n - 1 do
begin
Index := cxGrid1DBTableView1.DataController.GetSelectedRowIndex(i);
if Index < 0 then continue;
AccID :=
cxGrid1DBTableView1.DataController.GetRowvalue(
cxGrid1DBTableView1.DataController.GetRowInfo(Index)
,0);
AccID := dsData.DataSet.FieldByName(’AccountID’).AsString;
end;
n := cxGrid1DBTableView1.DataController.GetSelectedCount;
for i:=0 to n - 1 do
begin
Index := cxGrid1DBTableView1.DataController.GetSelectedRowIndex(i);
if Index < 0 then continue;
AccID := cxGrid1DBTableView1.DataController.GetRowvalue(
cxGrid1DBTableView1.DataController.GetRowInfo(Index)
,0);//这里的0是列的索引,能指定,也可用通过GridView获取
end;
****************************************************************************
61 动态设置显示格式
解决:
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;
****************************************************************************
62 给cxGRID加序号列
解决:
procedure SetRowNumber(var ASender: TcxGridTableView;
AViewInfo: TcxCustomGridIndicatorItemViewInfo;
var ACanvas: TcxCanvas; var ADone: boolean);
uses cxLookAndFeelPainters;
procedure SetRowNumber(var ASender: TcxGridTableView; AViewInfo: TcxCustomGridIndicatorItemViewInfo;
var ACanvas: TcxCanvas; var ADone: boolean);
var
AIndicatorViewInfo: TcxGridIndicatorRowItemViewInfo;
ATextRect: TRect;
AFont: TFont;
AFontTextColor, AColor: TColor;
begin
AFont := ACanvas.Font;
AColor := clBtnFace;
AFontTextColor := clWindowText ;
if (AViewInfo is TcxGridIndicatorHeaderItemViewInfo) then begin
ATextRect := AViewInfo.Bounds;
InflateRect(ATextRect, -1, -1);
ASender.LookAndFeelPainter.DrawHeader(ACanvas, AViewInfo.Bounds,
ATextRect, [], cxBordersAll, cxbsNormal, taCenter, vaCenter,
False, False, ‘序号‘, AFont, AFontTextColor, AColor);
ADone := True;
end ;
if not (AViewInfo is TcxGridIndicatorRowItemViewInfo) then
Exit;
ATextRect := AViewInfo.ContentBounds;
AIndicatorViewInfo := AViewInfo as TcxGridIndicatorRowItemViewInfo;
InflateRect(ATextRect, -1, -1);
ASender.LookAndFeelPainter.DrawHeader(ACanvas, AViewInfo.ContentBounds,
ATextRect, [], [bBottom, bLeft, bRight], cxbsNormal, taCenter, vaCenter,
False, False, IntToStr(AIndicatorViewInfo.GridRecord.Index + 1),
AFont, AFontTextColor, AColor);
ADone := True;
ASender.LookAndFeelPainter.DrawIndicatorImage(ACanvas,ATextRect, AIndicatorViewInfo.IndicatorKind);
end;
如果你不要行标志的话,你可以不改控件
直接注释掉这一行: ASender.LookAndFeelPainter.DrawIndicatorImage(ACanvas, ATextRect, AIndicatorViewInfo.IndicatorKind);
要标志的话,在DrawIndicatorImage 从这里跟进去(Ctrl+左键单击)
在 cxLookAndFeelPainters 单元中作如下修改:
class procedure TcxCustomLookAndFeelPainter.DrawIndicatorImage(ACanvas: TcxCanvas;
const R: TRect; AKind: TcxIndicatorKind);
var
X, Y: Integer;
begin
if AKind = ikNone then Exit;
with cxIndicatorImages, R do
begin
X := (Left + Right - Width); //靠右
Y := (Top + Bottom - Height) div 2; //居中
end;
cxIndicatorImages.Draw(ACanvas.Canvas, X, Y, Ord(AKind) - 1);
end;
注意,我已注明靠右的那一行, 就是去掉 DIV 2 了,
还要改一个地方:
SKIN控件目录下的dxSkinLookAndFeelPainter单元,找到
TdxSkinLookAndFeelPainter.DrawIndicatorImage 函数
的
OffsetRect(ARect, (Left + Right - cx div 2) , (Top + Bottom - cy) div 2);
这一行,将 (Left + Right - cx div 2) 改为(Left + Right - cx) 也是去掉 div 2 就是靠右;
修改后: OffsetRect(ARect, (Left + Right - cx) , (Top + Bottom - cy) div 2);
使用
procedure TForm1.cxGrid1DBTableView1CustomDrawIndicatorCell(
Sender: TcxGridTableView; ACanvas: TcxCanvas;
AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean);
begin
SetRowNumber(Sender,AviewInfo,ACanvas,ADone);
end;
另外序号列的列宽最好改为25以上!
效果图:
****************************************************************************
63 cxGrid自带过滤后数据也数据集同步
解决:
在cxGrid的View Filter事件的OnBeforeChange中写代码就可以了.
procedure TForm1.tvcxgd1DBTableView1DataControllerFilterBeforeChange( Sender: TcxDBDataFilterCriteria; ADataSet: TDataSet; const AFilterText: String); begin //这里可以增加数据集控件的filter:=false; //如:adoquery.filter:=false; //如果使用的是cxgrid的汉化版本,可以将AFilterText中的中文等于,小于 替换成 = <等 //adoquery.filter:=替换了中文的AFilterText; ShowMessage(AFilterText); end; 写了上述步骤后可以在tvcxgd1DBTableView1DataControllerFilterChanged写 adoquery.filter:=true; 这样就起到了cxgrid过滤后的数据同步到adoquery
以上是关于delphi CxGrid用法总结(63问)的主要内容,如果未能解决你的问题,请参考以下文章