cxGrid 部分使用方法(2)

来源:互联网 发布:淘宝远程刷机靠谱吗 编辑:程序博客网 时间:2024/05/21 22:57

激活内置编辑控件

1) <aView>.Controller.EditingController.ShowEdit(<aColumn>); 
2) <aView>.Controller.EditingController.StartEditShowingTimer(<aColumn>); 
3) <aView>.Controller.EditingItem := <aColumn>; 
4) <aColumn>.Editing := True;

隐藏内置编辑控件 
<aView>.Controller.EditingController.HideEdit(True);

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

移除一个分组列

<aColumn>.GroupIndex := -1; 
<aColumn>.Visible := True;

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

保存修改到数据库

procedure <aForm>.FormClose(Sender: TObject; var Action: TCloseAction); 
begin 
if (<aGrid>.FocusedView <> nil) and (<aGrid>.FocusedView.DataController.EditState <> []) then 
<aGrid>.FocusedView.DataController.Post; 
end;

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

设置内置右键菜单

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

uses cxGridStdPopupMenu;

procedure TForm1.cxGridPopupMenu1Popup(ASenderMenu: TComponent; 
AHitTest: TcxCustomGridHitTest; X, Y: Integer; var AllowPopup: Boolean); 
begin 
if ASenderMenu is TcxGridStdHeaderMenu then 
TcxGridStdHeaderMenu(ASenderMenu).OnPopup := StdHeaderMenuPopup; 
end;

procedure TForm1.StdHeaderMenuPopup(Sender: TObject); 
var 
I: Integer; 
begin 
with TcxGridStdHeaderMenu(Sender).Items do 
for I := 0 to Count - 1 do 
if Items[I].Caption = 'Group By Box' then 
begin 
Items[I].Enabled := False; 
System.Break; 
end 
end;

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

得到选中记录的值

1) View.DataController.DataModeController.GridMode = False时

RecIdx := View.Controller.SelectedRecords[i].RecordIndex; 
ColIdx := View.DataController.GetItemByFieldName(AFieldName).Index; 
OutputVal := View.DataController.Values[RecIdx, ColIdx];

//RecID := View.DataController.GetRecordId(RecIdx); 
//OutputVal := ADataSet.Lookup(View.DataController.KeyFieldNames, RecID, AFieldName);

2) View.DataController.DataModeController.GridMode = True时 
Bkm := View.DataController.GetSelectedBookmark(ASelectedRecordIndex); 
if ADataSet.BookmarkValid(TBookmark(Bkm)) then 
begin 
ADataSet.Bookmark := TBookmark(Bkm); 
OutputVal := ADataSet.FieldByName(AFieldName).Value; 
end;

View.BeginUpdate; 
View.DataController.BeginLocate; 
try 
// make changes here… 
finally 
View.DataController.EndLocate; 
View.EndUpdate; 
end;

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

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

uses cxGridStdPopupMenu;

procedure cxGridPopupMenuOnPopup(...) 
begin 
if (ASenderMenu is TcxGridStdFooterMenu) and 
<GridView>.DataController.DataModeController.GridMode then 
AllowPopup := False; 
end;

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

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

procedure TForm1.ADetailDataControllerCollapsing( 
ADataController: TcxCustomDataController; ARecordIndex: Integer; 
var AAllow: Boolean); 
var 
I: Integer; 
C: Integer; 
begin 
AAllow := False; 
C := 0; 
for I := 0 to ADataController.RecordCount - 1 do 
begin 
if ADataController.GetDetailExpanding(I) then 
Inc(C); 
if C > 1 then 
AAllow := True; 
end; 
end;

procedure TForm1.ADetailDataControllerExpanding( 
ADataController: TcxCustomDataController; ARecordIndex: Integer; 
var AAllow: Boolean); 
begin 
ADataController.CollapseDetails; 
end;

procedure TForm1.FormCreate(Sender: TObject); 
begin 
cxGrid1DBTableView1.DataController.OnDetailExpanding := ADetailDataControllerExpanding; 
cxGrid1DBTableView1.DataController.OnDetailCollapsing := ADetailDataControllerCollapsing; 
end;

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

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

var 
Grid: TcxGrid; 
Level: TcxGridLevel; 
View: TcxGridDBTableView; 
begin 
// Creates a Grid instance 
Grid := TcxGrid.Create(SomeOwner); 
Grid.Parent := SomeParent; 
// Creates a Level 
Level := Grid.Levels.Add; 
Level.Name := 'SomeLevelName'; 
// Creates a View 
View := Grid.CreateView(TcxGridDBTableView) as TcxGridDBTableView; 
View.Name := 'SomeViewName'; 
// … and binds it to the Level 
Level.GridView := View; 
// Hooks up the View to the data 
View.DataController.DataSource := SomeDataSource; 
// … and creates all columns 
View.DataController.CreateAllItems; 
end;

 

此楼回复Re: 
--------------------------------------------------------------------------------

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

获得Group Footer合计行对应的记录

procedure TForm1.cxGrid1DBTableView1CustomDrawFooterCell( 
Sender: TcxGridTableView; ACanvas: TcxCanvas; 
AViewInfo: TcxGridColumnHeaderViewInfo; var ADone: Boolean); 
var 
ALevel, ADataGroupIndex: Integer; 
AGridRecord, AGroupRecord: TcxCustomGridRecord; 
begin 
if AViewInfo is TcxGridRowFooterCellViewInfo and // Row footer 
(TcxGridDBColumn(AViewInfo.Column).DataBinding.FieldName = 'Area') then // Area column 
begin 
AGridRecord := TcxGridRowFooterCellViewInfo(AViewInfo).GridRecord; 
ALevel := TcxGridRowFooterCellViewInfo(AViewInfo).Container.GroupLevel; 
ADataGroupIndex := Sender.DataController.Groups.DataGroupIndexByRowIndex[AGridRecord.Index]; 
if ADataGroupIndex <> -1 then 
begin 
AGroupRecord := AGridRecord; 
while AGroupRecord.Level <> ALevel do 
AGroupRecord := AGroupRecord.ParentRecord; 
AViewInfo.Text := AGroupRecord.DisplayTexts[0]; 
end; 
end; 
end;

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

访问过滤之后的记录

var 
I: Integer; 
begin 
Memo1.Lines.Clear; 
with cxGrid1DBTableView1.DataController do 
for I := 0 to FilteredRecordCount - 1 do 
Memo1.Lines.Add(DisplayTexts[FilteredRecordIndex[I], 0]); 
end;

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

获得单元的Font

cxGrid1DBTableView1.ViewInfo.RecordsViewInfo.Items[1].GetCellViewInfoByItem( 
cxGrid1DBTableView1Company).EditViewInfo.Font;

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

根据Level名称找到Level对象

function GetLevelByName(AGrid: TcxGrid; ALevelName: string): TcxGridLevel;

function LoopThroughLevels(ALevel: TcxGridLevel; ALevelName: string): TcxGridLevel; 
var 
I: Integer; 
begin 
Result := nil; 
for I := 0 to ALevel.Count - 1 do 
begin 
if ALevel[I].Name = ALevelName then 
begin 
Result := ALevel[I]; 
Exit; 
end; 
if ALevel[I].Count > 0 then 
begin 
Result := LoopThroughLevels(ALevel[I], ALevelName); 
if Result <> nil then 
Exit; 
end; 
end; 
end;

var 
I: Integer; 
begin 
Result := nil; 
for I := 0 to AGrid.Levels.Count - 1 do 
begin 
if AGrid.Levels[I].Name = ALevelName then 
begin 
Result := AGrid.Levels[I]; 
Exit; 
end; 
if AGrid.Levels[I].Count > 0 then 
begin 
Result := LoopThroughLevels(AGrid.Levels[I], ALevelName); 
if Result <> nil then 
Exit; 
end; 
end; 
end;

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

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

uses 
..., cxFilterControlDialog;

procedure TForm.GridView1FilterControlDialogShow( 
Sender: TObject); 
begin 
TfmFilterControlDialog(Sender).OpenDialog.InitialDir := 'D:/' 
end;

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

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

<TableView>.StoreToIniFile('c:/Grid.ini', True, [gsoUseSummary]); 
<GridView>.RestoreFromIniFile(<inifilename>,True,False {or True, optional},[gsoUseSummary]);

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

取消过滤时移到第一行

uses 
cxCustomData;

procedure TYour_Form.AViewDataControllerFilterChanged(Sender: TObject); 
var 
Filter: TcxDataFilterCriteria; 
begin 
with Sender as TcxDataFilterCriteria do 
if IsEmpty then 
DataController.FocusedRowIndex := 0; 
end;

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

排序后移到第一行

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

uses 
cxCustomData;

procedure TYour_Form.Your_ViewDataControllerSortingChanged(Sender: TObject); 
begin 
TcxCustomDataController(Sender).FocusedRowIndex := 0; 
end;

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

判断当前行是否第一行或最后一行

可以使用DataController的IsBOF, IsEOF方法,或者: 
<AView>.Controller.Controller.FocusedRow.IsFirst 
<AView>.Controller.Controller.FocusedRow.IsLast

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

根据指定值查找记录

DataController提供了好几个方法来得到指定值对应的RecordIndex 
对于Bound View可以使用FindRecordIndexByKeyValue方法

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

编辑和显示Blob字段

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

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

得到可见行数

<View>.ViewInfo.VisibleRecordCount

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

保存后的行设置为当前行

const 
CM_SETFOCUSEDRECORD = WM_USER + 1002;

type 
TForm1 = class(TForm) 
cxGrid1DBTableView1: TcxGridDBTableView; 
cxGrid1Level1: TcxGridLevel; 
cxGrid1: TcxGrid; 
dxMemData1: TdxMemData; 
dxMemData1Field1: TStringField; 
dxMemData1Field2: TIntegerField; 
DataSource1: TDataSource; 
cxGrid1DBTableView1RecId: TcxGridDBColumn; 
cxGrid1DBTableView1Field1: TcxGridDBColumn; 
cxGrid1DBTableView1Field2: TcxGridDBColumn; 
Timer1: TTimer; 
CheckBox1: TCheckBox; 
procedure Timer1Timer(Sender: TObject); 
procedure dxMemData1AfterPost(DataSet: TDataSet); 
procedure CheckBox1Click(Sender: TObject); 
private 
procedure CMSetFocusedRecord(var Msg: TMessage); message CM_SETFOCUSEDRECORD; 
public 
{ Public declarations } 
end;

var 
Form1: TForm1; 
FocusedIdx: Integer;


implementation

{$R *.dfm}

procedure TForm1.Timer1Timer(Sender: TObject); 
begin 
dxMemData1.AppendRecord(['', IntToStr(Random(1000)), Random(1000)]); 
end;

procedure TForm1.dxMemData1AfterPost(DataSet: TDataSet); 
begin 
PostMessage(Handle, CM_SETFOCUSEDRECORD, Integer(cxGrid1DBTableView1), MakeLParam(cxGrid1DBTableView1.Controller.FocusedRowIndex, cxGrid1DBTableView1.Controller.TopRowIndex)); 
end;

procedure TForm1.CMSetFocusedRecord(var Msg: TMessage); 
begin 
TcxGridDBTableView(msg.WParam).Controller.FocusedRowIndex := Msg.LParamLo; 
TcxGridDBTableView(msg.WParam).Controller.TopRowIndex := Msg.LParamHi; 
end;

procedure TForm1.CheckBox1Click(Sender: TObject); 
begin 
Timer1.Enabled := TCheckBox(Sender).Checked; 
end;

end.

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

删除记录并获得焦点

procedure TForm1.BtnDeleteClick(Sender: TObject); 
var 
FocusedRow, TopRow: Integer; 
View: TcxGridTableView; 
DataController: TcxGridDataController; 
begin 
View := cxGrid1.FocusedView as TcxGridTableView; 
DataController := View.DataController;

// Remember the top row (the vertical scrollbar position) 
TopRow := View.Controller.TopRowIndex; 
// Remember the focused row(!) index 
FocusedRow := DataController.FocusedRowIndex;

DataController.DeleteFocused;

// After deletion the same row must be focused, 
// although it will correspond to a different data record 
DataController.FocusedRowIndex := FocusedRow; 
// Restore the top row 
View.Controller.TopRowIndex := TopRow; 
end;

//=======================================================================================
数据库中的财务表为: 
ID 收支类型 金额 其它属性

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

设置cxGrid的Footer 可以使得在显示时,列表的下方出现汇总行:“金额”的和 
同样设置Default For Groups可以使得在用户拖动表头属性实现分组时,显示组内的汇总行:“金额”的和。

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

如果我想使汇总行的值变为如下的值应该怎样实现: 
收支类型为0的金额的和 - 收支类型为1的金额的和 
实现Footer的功能好办,因为它的值不会变,自己用循环写一个就完了,但是Default For Groups的功能就不好说了,因为它的值是根据用户拖动的属性计算的,而且还有可能是多层分组,想不出来了,所有到这来问 
是不是要设置什么属性?或者cxGrid根本就没这个功能,那该用什么方法解决?希望哪位帮我解决,谢谢了先!

给你一个例子,可能对你有帮助, 
with tvOrders.DataController.Summary do

begin 
BeginUpdate; 
try 
SummaryGroups.Clear; 
//The first summary group 
with SummaryGroups.Add do 
begin 
//Add proposed grouping column(s) 
TcxGridTableSummaryGroupItemLink(Links.Add).Column := tvOrdersCustomerID; 
//Add summary items 
with SummaryItems.Add as TcxGridDBTableSummaryItem do 
begin 
Column := tvOrdersPaymentAmount; 
Kind := skSum; 
Format := 'Amount Paid: $,0'; 
end;

with SummaryItems.Add as TcxGridDBTableSummaryItem do 
begin 
Column := tvOrdersPaymentAmount; 
Kind := skCount; 
Format := 'Records: 0'; 
end;

end;

//The second summary group 
with SummaryGroups.Add do 
begin 
//Add proposed grouping column(s) 
TcxGridTableSummaryGroupItemLink(Links.Add).Column := tvOrdersProductID; 
//Add summary items 
with SummaryItems.Add as TcxGridDBTableSummaryItem do 
begin 
Column := tvOrdersQuantity; 
Kind := skSum; 
Position := spFooter; 
Format := 'TOTAL = 0'; 
end;

with SummaryItems.Add as TcxGridDBTableSummaryItem do 
begin 
Column := tvOrdersPurchaseDate; 
Kind := skMin; 
Position := spFooter; 
end; 
end;

finally 
EndUpdate; 
end; 
end; 2007-7-19 12:56:41 go on 
订单号 商品名 单价 数量 金额
001 aa 11.00 2 22.00
001 bb 2.00 2 4.00
001 cc 3.00 3 9.00

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

002 ee 11.00 2 22.00
002 bb 3.00 2 6.00
002 cc 3.00 3 9.00

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


总计14 72.00

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

最后在底下实现总的合计

 


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


?
可以的,cxGrid的功能比你想象的还要强大。
1.你先放一个cxGrid,设置好View,设置View.DataController连接的DataSource
2.激活DataSource连接的DataSet,双击cxGrid,点击Retrieve Fields,取得所有的Column
3.设置View的OptionsView.Footer=True,OptionsView.GroupFooters=True,这是为了把分组小计和总计面板显示出来
4.将“订单号”字段拖到cxGrid上方的分组面板(GroupbyBox),将数据按“订单号”分组。这时你会发现单身所有的数据都缩起来了,如果想使所有的数据都展开,可以设置View.DataController.Options.dcoGroupsAlwaysExpanded=True
5.设置分组小计:把View.DataController.Summary.DefaultGroupSummaryItems点开,新增一个Item,Column属性在下拉里选择“数量”字段,FieldName属性为空,Format属性可以设置数值的显示格式,Kind属性下拉skSum加总,Position属性一定要选择spFooter。
6.设置总计:把View.DataController.Summary.FooterSummaryItems点开,新增一个Item,Column属性在下拉里选择“数量”字段,FieldName属性为空,Format属性可以设置数值的显示格式,Kind属性下拉skSum加总,Position属性一定要选择spFooter。
大功告成,按F9看一下胜利果实吧。

再奉送一个技巧,在Form1再放一个TcxGridPopupMenu控件,就在cxGrid控件旁边的那个,把TcxGridPopupMenu的Grid属性设置成你的cxGrid。
然后运行程序,在运行状态,点击Grid上的所有地方,左键或右键,你都会有意外收获。

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

0 0
原创粉丝点击