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;   

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

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

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;

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

获得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;

CXGrid的使用技巧的更多相关文章

  1. FastReport 使用技巧篇

    使用技巧篇 1.FastReport中如果访问报表中的对象?       可以使用FindObject方法.      TfrxMemoView(frxReport1.FindObject('memo ...

  2. cxGrid用法-最新

    cxGrid用法-最新 在做AdoHelper实用程序的时候,我用了DevExpress的cxGrid控件.在此之前用的是dbgrid,考虑到不能把所有的数据都拉到本地,我用了动态生成的select ...

  3. FastReport使用技巧

    使用技巧篇 1.FastReport中如果访问报表中的对象?       可以使用FindObject方法.      TfrxMemoView(frxReport1.FindObject('memo ...

  4. cxgrid强大用法

    cxgrid强大用法 (2012-07-25 14:09:42) 转载▼ 标签: delphi cxgrid 用法 强大 杂谈 分类: Delphi cxGrid功能强大,适合做企业级的复杂查询.非常 ...

  5. 探究javascript对象和数组的异同,及函数变量缓存技巧

    javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...

  6. 前端极易被误导的css选择器权重计算及css内联样式的妙用技巧

    记得大学时候,专业课的网页设计书籍里面讲过css选择器权重的计算:id是100,class是10,html标签是5等等,然后全部加起来的和进行比较... 我只想说:真是误人子弟,害人不浅! 最近,在前 ...

  7. 前端网络、JavaScript优化以及开发小技巧

    一.网络优化 YSlow有23条规则,中文可以参考这里.这几十条规则最主要是在做消除或减少不必要的网络延迟,将需要传输的数据压缩至最少. 1)合并压缩CSS.JavaScript.图片,静态资源CDN ...

  8. 工欲善其事,必先利其器 之 VS2013全攻略(安装,技巧,快捷键,插件)!

    如有需要WPF工具的朋友可以移步 工欲善其事,必先利其器 之 WPF篇: 随着开发轨迹来看高效WPF开发的工具和技巧 之前一篇<c++的性能, c#的产能?!鱼和熊掌可以兼得,.NET NATI ...

  9. 15个关于Chrome的开发必备小技巧[译]

    谷歌Chrome,是当前最流行且被众多web开发人员使用的浏览器.最快六周就更新发布一次以及伴随着它不断强大的开发组件,使得Chrome成为你必备的开发工具.例如,在线编辑CSS,console以及d ...

随机推荐

  1. 关于 jquery 选择器的 深入理解 -1

    多级选择器: 前面一个selector1, 后面通过 //空格, >, + ~, 各种筛选 选择器 + selector2 // 再次进行选择的,就叫做多级选择器 jquery的一个基本常识: ...

  2. [译]git checkout

    git checkout git checkout提供3种不同的功能: checking out文件, checking out commits, checking out branch. check ...

  3. VTK初学一,a Mesh from vtkImageData

    #ifndef INITIAL_OPENGL #define INITIAL_OPENGL #include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRend ...

  4. 电脑开机黑屏,显示Reboot and Select proper boot device!

    “reboot and select proper boot device or insert boot media in selected boot device and press a key” ...

  5. C#深入浅出 关键字(一)

    1.this this关键字用于指示当前对象“自己”,来看一个例子,了解什么时候需要用this class Star { String name; int age; public void SetIn ...

  6. javacomm64位用不了,可以使用RXTXcomm for x64

    安装完后把导入包名改一下就行了! 附上读串口代码: /* * @(#)SimpleRead.java 1.12 98/06/25 SMI * * Copyright (c) 1998 Sun Micr ...

  7. Springmvc + mybatis + spring 配置,spring事物

    今天配置了半天,发现,事物不起效果,主要出现如下错误: org.mybatis.spring.transaction.SpringManagedTransaction] - [JDBC Connect ...

  8. 网络编程3-URL编程(URL)

    1.URL(Uniform Resource Locatior) 统一资源占位符,表示Intenet上某一资源的地址 2.URL的组成部分 传输协议:主机名:端口号:文件名 例:http://192. ...

  9. svn 设置post-commit后 报错svn: Can't convert string from 'UTF-8' to native encoding

    文件语言编码和系统冲突导致的错误,设置svn目录下hooks/post-commit加上: export LANG=zh_CN.GB2312 或者: export LANG=zh_CN.UTF-8

  10. Android开发学习笔记--计时器的应用实例

    为了了解安卓计时器的用法,写了一个秒表的应用,正是这个秒表,让我对Android应用的速度大跌眼镜,我设置了一个计时器,10ms更新一次显示的时间,然后更标准的时间一比较发现,跑10s就有一秒的时间误 ...