您的位置:首页 > 编程语言 > Delphi

Delphi CxGrid 汇总(4)

2013-11-28 10:20 507 查看
1. CxGrid汇总功能

① OptionsView-Footer设置为True,显示页脚 ② CxGrid的Summary选项卡定义要汇总的列和字段名及汇总方式,Footer选项卡定义单个汇总,Default
For Groups定义按组汇总。OptionsView-GroupFooters设置为gfAlwaysVisible则显示按组汇总。设置后界面如图。





2. CxGrid的样式设置

当设置了Kind时,NativeStyle必须设置为False,如果指定了SkinName则Kind属性失效。



下图是设置skinname为MoneyTwins后效果



4. 取某个单元格的值

Cxgrid.DataController.Values[i,j]

5. 列操作,选择CxGrid控件后,点击“Customize”新建一列,在Columns集合中选中新建的列,选择propertites属性可以设置该列的显示形式。下面介绍常用的几个

① Properties选择CheckBox,则该列显示一个复选框,如下:


判断是否选中 if Cxgrid.DataController.Values[i,j]=’1’ 选中

② Properties选择ButtonEdit,并对该列的属性编辑器设置如下属性Buttons属性添加按钮项,对按钮项设置可以设置kind属性定义按钮样式;ViewStyle属性设置为vsButtonsOnly,Options-ShowEditButton设置为isebAlways。可以编写点击事件如下:

procedure TForm1.cxgrdbtblvwGrid1DBTableView1Column1PropertiesButtonClick(

Sender: TObject; AButtonIndex: Integer);

begin

ShowMessage('aaa');

end;

③ImageComboBox,可以关联一个imagelist,显示图片。如下关联imagelist后效果。



6.动态添加列和记录行

var

Column: TcxGridColumn;

i:integer;

acount:integer;

begin

Column:= cxgrd1TableView1.CreateColumn;

Column.Caption := 'Test ';

cxgrd1TableView1.DataController.AppendRecord;

cxgrd1TableView1.DataController.Values[0, 0] := 'ABC ';

cxgrd1TableView1.DataController.Post;

//添加多条记录

for i:=1 to 4 do

begin

acount:=cxgrd1TableView1.DataController.RecordCount;

cxgrd1TableView1.DataController.AppendRecord;

cxgrd1TableView1.DataController.Values[acount, 0] :=IntToStr(i*1);

cxgrd1TableView1.DataController.Post();

end;

end;

//删除记录

cxgrd1TableView1.DataController.DeleteRecord(0);

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 保存后的行设置为当前行

解决:

[delphi] view
plaincopy

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加序号列

解决:

[delphi] view
plaincopy

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中写代码就可以了.

[delphi] view
plaincopy

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: