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

Delphi CxGrid 汇总(5)

2013-04-19 16:46 886 查看

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