delphi CxGrid用法总结(63问)
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