cxGrid 使用指南 2

2016-08-22 10:23:41来源:http://amcto111.blog.51cto.com/351775/1441406作者:kindao人点击


CxGrid使用小结(续)

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



激活内置编辑控件



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;varAction:TCloseAction);

begin

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

<aGrid>.FocusedView.DataController.Post;

end;



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



设置内置右键菜单



内置右键菜单包括二个菜单:cxGridStdHeaderMenu,TcxGridStdFooterMenu



usescxGridStdPopupMenu;



procedureTForm1.cxGridPopupMenu1Popup(ASenderMenu:TComponent;

AHitTest:TcxCustomGridHitTest;X,Y:Integer;varAllowPopup:Boolean);

begin

ifASenderMenuisTcxGridStdHeaderMenuthen

TcxGridStdHeaderMenu(ASenderMenu).OnPopup:=StdHeaderMenuPopup;

end;



procedureTForm1.StdHeaderMenuPopup(Sender:TObject);

var

I:Integer;

begin

withTcxGridStdHeaderMenu(Sender).Itemsdo

forI:=0toCount-1do

ifItems[I].Caption='GroupByBox'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);

ifADataSet.BookmarkValid(TBookmark(Bkm))then

begin

ADataSet.Bookmark:=TBookmark(Bkm);

OutputVal:=ADataSet.FieldByName(AFieldName).Value;

end;



View.BeginUpdate;

View.DataController.BeginLocate;

try

//makechangeshere…

finally

View.DataController.EndLocate;

View.EndUpdate;

end;



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



在GridMode禁用内置的右键Footer菜单



usescxGridStdPopupMenu;



procedurecxGridPopupMenuOnPopup(...)

begin

if(ASenderMenuisTcxGridStdFooterMenu)and

<GridView>.DataController.DataModeController.GridModethen

AllowPopup:=False;

end;



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



主从表任何时候只能展开一个组



procedureTForm1.ADetailDataControllerCollapsing(

ADataController:TcxCustomDataController;ARecordIndex:Integer;

varAAllow:Boolean);

var

I:Integer;

C:Integer;

begin

AAllow:=False;

C:=0;

forI:=0toADataController.RecordCount-1do

begin

ifADataController.GetDetailExpanding(I)then

Inc(C);

ifC>1then

AAllow:=True;

end;

end;



procedureTForm1.ADetailDataControllerExpanding(

ADataController:TcxCustomDataController;ARecordIndex:Integer;

varAAllow:Boolean);

begin

ADataController.CollapseDetails;

end;



procedureTForm1.FormCreate(Sender:TObject);

begin

cxGrid1DBTableView1.DataController.OnDetailExpanding:=ADetailDataControllerExpanding;

cxGrid1DBTableView1.DataController.OnDetailCollapsing:=ADetailDataControllerCollapsing;

end;



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



动态创建层次(Level)和视图(View)



var

Grid:TcxGrid;

Level:TcxGridLevel;

View:TcxGridDBTableView;

begin

//CreatesaGridinstance

Grid:=TcxGrid.Create(SomeOwner);

Grid.Parent:=SomeParent;

//CreatesaLevel

Level:=Grid.Levels.Add;

Level.Name:='SomeLevelName';

//CreatesaView

View:=Grid.CreateView(TcxGridDBTableView)asTcxGridDBTableView;

View.Name:='SomeViewName';

//…andbindsittotheLevel

Level.GridView:=View;

//HooksuptheViewtothedata

View.DataController.DataSource:=SomeDataSource;

//…andcreatesallcolumns

View.DataController.CreateAllItems;

end;







此楼回复Re:

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



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



获得GroupFooter合计行对应的记录



procedureTForm1.cxGrid1DBTableView1CustomDrawFooterCell(

Sender:TcxGridTableView;ACanvas:TcxCanvas;

AViewInfo:TcxGridColumnHeaderViewInfo;varADone:Boolean);

var

ALevel,ADataGroupIndex:Integer;

AGridRecord,AGroupRecord:TcxCustomGridRecord;

begin

ifAViewInfoisTcxGridRowFooterCellViewInfoand//Rowfooter

(TcxGridDBColumn(AViewInfo.Column).DataBinding.FieldName='Area')then//Areacolumn

begin

AGridRecord:=TcxGridRowFooterCellViewInfo(AViewInfo).GridRecord;

ALevel:=TcxGridRowFooterCellViewInfo(AViewInfo).Container.GroupLevel;

ADataGroupIndex:=Sender.DataController.Groups.DataGroupIndexByRowIndex[AGridRecord.Index];

ifADataGroupIndex<>-1then

begin

AGroupRecord:=AGridRecord;

whileAGroupRecord.Level<>ALeveldo

AGroupRecord:=AGroupRecord.ParentRecord;

AViewInfo.Text:=AGroupRecord.DisplayTexts[0];

end;

end;

end;



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



访问过滤之后的记录



var

I:Integer;

begin

Memo1.Lines.Clear;

withcxGrid1DBTableView1.DataControllerdo

forI:=0toFilteredRecordCount-1do

Memo1.Lines.Add(DisplayTexts[FilteredRecordIndex[I],0]);

end;



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



获得单元的Font



cxGrid1DBTableView1.ViewInfo.RecordsViewInfo.Items[1].GetCellViewInfoByItem(

cxGrid1DBTableView1Company).EditViewInfo.Font;



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



根据Level名称找到Level对象



functionGetLevelByName(AGrid:TcxGrid;ALevelName:string):TcxGridLevel;



functionLoopThroughLevels(ALevel:TcxGridLevel;ALevelName:string):TcxGridLevel;

var

I:Integer;

begin

Result:=nil;

forI:=0toALevel.Count-1do

begin

ifALevel[I].Name=ALevelNamethen

begin

Result:=ALevel[I];

Exit;

end;

ifALevel[I].Count>0then

begin

Result:=LoopThroughLevels(ALevel[I],ALevelName);

ifResult<>nilthen

Exit;

end;

end;

end;



var

I:Integer;

begin

Result:=nil;

forI:=0toAGrid.Levels.Count-1do

begin

ifAGrid.Levels[I].Name=ALevelNamethen

begin

Result:=AGrid.Levels[I];

Exit;

end;

ifAGrid.Levels[I].Count>0then

begin

Result:=LoopThroughLevels(AGrid.Levels[I],ALevelName);

ifResult<>nilthen

Exit;

end;

end;

end;



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



指定FilterBuilder打开/保存过滤文件的默认路径



uses

...,cxFilterControlDialog;



procedureTForm.GridView1FilterControlDialogShow(

Sender:TObject);

begin

TfmFilterControlDialog(Sender).OpenDialog.InitialDir:='D:/'

end;



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



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



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

<GridView>.RestoreFromIniFile(<inifilename>,True,False{orTrue,optional},[gsoUseSummary]);



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



取消过滤时移到第一行



uses

cxCustomData;



procedureTYour_Form.AViewDataControllerFilterChanged(Sender:TObject);

var

Filter:TcxDataFilterCriteria;

begin

withSenderasTcxDataFilterCriteriado

ifIsEmptythen

DataController.FocusedRowIndex:=0;

end;



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



排序后移到第一行



可以设置DataController.Options.FocusTopRowAfterSorting:=True,也可以使用如下的代码:



uses

cxCustomData;



procedureTYour_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

对于BoundView可以使用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;

procedureTimer1Timer(Sender:TObject);

proceduredxMemData1AfterPost(DataSet:TDataSet);

procedureCheckBox1Click(Sender:TObject);

private

procedureCMSetFocusedRecord(varMsg:TMessage);messageCM_SETFOCUSEDRECORD;

public

{Publicdeclarations}

end;



var

Form1:TForm1;

FocusedIdx:Integer;





implementation



{$R*.dfm}



procedureTForm1.Timer1Timer(Sender:TObject);

begin

dxMemData1.AppendRecord(['',IntToStr(Random(1000)),Random(1000)]);

end;



procedureTForm1.dxMemData1AfterPost(DataSet:TDataSet);

begin

PostMessage(Handle,CM_SETFOCUSEDRECORD,
Integer(cxGrid1DBTableView1),
MakeLParam(cxGrid1DBTableView1.Controller.FocusedRowIndex,

cxGrid1DBTableView1.Controller.TopRowIndex));

end;



procedureTForm1.CMSetFocusedRecord(varMsg:TMessage);

begin

TcxGridDBTableView(msg.WParam).Controller.FocusedRowIndex:=Msg.LParamLo;

TcxGridDBTableView(msg.WParam).Controller.TopRowIndex:=Msg.LParamHi;

end;



procedureTForm1.CheckBox1Click(Sender:TObject);

begin

Timer1.Enabled:=TCheckBox(Sender).Checked;

end;



end.



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



删除记录并获得焦点



procedureTForm1.BtnDeleteClick(Sender:TObject);

var

FocusedRow,TopRow:Integer;

View:TcxGridTableView;

DataController:TcxGridDataController;

begin

View:=cxGrid1.FocusedViewasTcxGridTableView;

DataController:=View.DataController;



//Rememberthetoprow(theverticalscrollbarposition)

TopRow:=View.Controller.TopRowIndex;

//Rememberthefocusedrow(!)index

FocusedRow:=DataController.FocusedRowIndex;



DataController.DeleteFocused;



//Afterdeletionthesamerowmustbefocused,

//althoughitwillcorrespondtoadifferentdatarecord

DataController.FocusedRowIndex:=FocusedRow;

//Restorethetoprow

View.Controller.TopRowIndex:=TopRow;

end;



//=======================================================================================

数据库中的财务表为:

ID收支类型金额其它属性



其中收支类型只有两种值:0表示收入,1表示支出;金额都是正数。



设置cxGrid的Footer可以使得在显示时,列表的下方出现汇总行:“金额”的和

同样设置DefaultForGroups可以使得在用户拖动表头属性实现分组时,显示组内的汇总行:“金额”的和。



上面说的,用过cxGrid应该都会,下面就有这么一个问题



如果我想使汇总行的值变为如下的值应该怎样实现:

收支类型为0的金额的和-收支类型为1的金额的和

实现Footer的功能好办,因为它的值不会变,自己用循环写一个就完了,但是DefaultForGroups的功能就不好说了,因为它的值是根据用户拖动的属性计算的,而且还有可能是多层分组,想不出来了,所有到这来问

是不是要设置什么属性?或者cxGrid根本就没这个功能,那该用什么方法解决?希望哪位帮我解决,谢谢了先!



给你一个例子,可能对你有帮助,

withtvOrders.DataController.Summarydo



begin

BeginUpdate;

try

SummaryGroups.Clear;

//Thefirstsummarygroup

withSummaryGroups.Adddo

begin

//Addproposedgroupingcolumn(s)

TcxGridTableSummaryGroupItemLink(Links.Add).Column:=tvOrdersCustomerID;

//Addsummaryitems

withSummaryItems.AddasTcxGridDBTableSummaryItemdo

begin

Column:=tvOrdersPaymentAmount;

Kind:=skSum;

Format:='AmountPaid:$,0';

end;



withSummaryItems.AddasTcxGridDBTableSummaryItemdo

begin

Column:=tvOrdersPaymentAmount;

Kind:=skCount;

Format:='Records:0';

end;



end;



//Thesecondsummarygroup

withSummaryGroups.Adddo

begin

//Addproposedgroupingcolumn(s)

TcxGridTableSummaryGroupItemLink(Links.Add).Column:=tvOrdersProductID;

//Addsummaryitems

withSummaryItems.AddasTcxGridDBTableSummaryItemdo

begin

Column:=tvOrdersQuantity;

Kind:=skSum;

Position:=spFooter;

Format:='TOTAL=0';

end;



withSummaryItems.AddasTcxGridDBTableSummaryItemdo

begin

Column:=tvOrdersPurchaseDate;

Kind:=skMin;

Position:=spFooter;

end;

end;



finally

EndUpdate;

end;

end;



2007-7-1912:56:41goon

订单号商品名单价数量金额

001aa11.00222.00

001bb2.0024.00

001cc3.0039.00



----------------------合计735.00



002ee11.00222.00

002bb3.0026.00

002cc3.0039.00



----------------------合计737.00





总计1472.00



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



最后在底下实现总的合计









回复人:dctony()()信誉:1002007-1-1221:48:23得分:100





?

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

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

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

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

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

5.设置分组小计:把View.DataController.Summary.DefaultGroupSummaryItems点开,新增一个
Item,Column属性在下拉里选择“数量”字段,FieldName属性为空,Format属性可以设置数值的显示格式,Kind属性下拉
skSum加总,Position属性一定要选择spFooter。

6.设置总计:把View.DataController.Summary.FooterSummaryItems点开,新增一个Item,Column
属性在下拉里选择“数量”字段,FieldName属性为空,Format属性可以设置数值的显示格式,Kind属性下拉skSum加
总,Position属性一定要选择spFooter。

大功告成,按F9看一下胜利果实吧。









1:cxgrid是应该数据关联的控件,类似dbgrid。

2:一般用来查阅表信息,如果要修改的话,直接在上面编辑或添加非常不方便

通常要放几个EDit来对选中的记录进行编辑或添加记录。

因为表一般都有主键,而用cxgrid很难控制。在post之前的主键检查工作。

3:由于没有直接进行编辑,而post之前又要进行主键检查工作(需要循环

adoquery,此时的记录索引已经改变了)。所以我们要用一个bookmack。在编辑

的时候先Getbookmack,在确认修改数据的时候,先GotoBookMark,再把值更新。

4:在选择某条记录后,需要得到相应的字段值显示在Edit上面,这个时候就要用

cxGridDBTableView的Cellclick事件里面处理;

可以用click事件里面的一个参数:ACellViewInfo。该参数的一个属性;

如:EdtMperson.text:=ACellViewInfo.GridRecord.Values[2];

5:当需要得到随即选择的多条记录时有两种办法

qrymast是一个adoquery

⑴第一步得到选择的总数

Icount:=cxGrid1DBTableView1.DataController.GetSelectedCount;


⑵循环所有所选择的记录

forn:=0toicount-1do

begin

⑶将选择记录的索引转换为数据集的索引

i:=cxGrid1DBTableView1.DataController.GetSelectedRowIndex(n);

如果cxgriddbtableview没有设置排序,那么第一种方法也是正确的(因为cxgriddbtableview显示

的数据和qrymast显示的数据顺序是一样的)



//这是第一种方法,取qrymast的数据

inc(i);//因为qrymast的记录是从1开始的

qryMast.RecNo:=i;

得到需要的数据值

listbox1.Items.Add(qrymast.fields[0].asstring);


//这是第二种方法,取cxGrid1DBTableView1.ViewData的数据

ifi=0then

cxGrid1DB.DataController.GotoFirst

else

cxGrid1DBTableView1.DataController.RecNo:=i;

str:=cxGrid1DBTableView1.ViewData.Rows[i].Values[0];

listbox1.Items.Add(str);

end;



(一次测试的时候,cxGrid1DBTableView1.DataController.RecNo:=0;语句会报错,如果改为cxGrid1DB.DataController.GotoFirst,就没有问题)

6:当有时候用到ACellViewInfo.GridRecord.Values[2]时候,由于values[2]是一个变体

类型Variant,而如果这个时候相应的字段值如果为空,下面这样用就会报错。

EdtMperson.text:=ACellViewInfo.GridRecord.Values[2];

可以先判断一下:

ifACellViewInfo.GridRecord.Values[4]<>nullthen

MemRdesc.Lines.Text:=ACellViewInfo.GridRecord.Values[4];

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台