delphi CXGRID用法 ,取行、列值;定位选中某行等等

CXGRID用法 (取行、列值;定位选中某行等等)

Delphi Cxgrid获取选中行列,排序规则,当前正在编辑的单元格内的值

cxGrid1DBTableView1.Controller.FocusedRowIndex 当前行号

cxGrid1DBTableView1.Controller.FocusedRow 当前行

cxGrid1DBTableView1.Controller.FocusedColumn 当前列

cxGrid1DBTableView1.Controller.FocusedColumnIndex 当前列号

cxGrid1DBTableView1.Controller.EditingItem 当前编辑中的单元框

cxGrid1DBTableView1.Controller.EditingController.Edit 当前的编辑框

在编辑状态下可以这样取当前单元格的值:

if cxGrid1DBTableView1.Controller.FocusedColumn.Editing then

ShowMessage(cxGrid1DBTableView1.Controller.EditingController.Edit.EditingValue)

else

cxGrid1DBTableView1.DataController.GetValue(cxGrid1DBTableView1.DataController.FocusedRecordIndex, cxGrid1DBTableView1.Controller.FocusedItemIndex);

非编辑状态下可以这样取得单元格内的值:

OnCellClick事件代码:

procedure TForm1.cxGrid1DBTableView1CellClick( Sender: TcxCustomGridTableView;

ACellViewInfo: TcxGridTableDataCellViewInfo; AButton: TMouseButton; AShift: TShiftState; var AHandled: Boolean); var

v : Variant; begin

v := ACellViewInfo.Value; end;

取列值

i := cxGrid1DBBandedTableView1.Controller.FocusedColumn.Index;

cxGrid1DBBandedTableView1.DataController.GetValue(cxGrid1DBBandedTableView1.Controller.SelectedRows[0].RecordIndex,i);

cxGrid1DBTableView1.DataController.Values[行,列]

取得焦点

cxGrid1DBTableView1.Columns[5].FocusWithSelection; cxGrid1DBTableView1.Columns[4].Focused:=True;

得到当前点击的单元格的值

uses Clipbrd;

OnCellClick事件代码: procedure TForm1.cxGrid1DBTableView1CellClick( Sender: TcxCustomGridTableView; ACellViewInfo: TcxGridTableDataCellViewInfo; AButton: TMouseButton; AShift: TShiftState; var AHandled: Boolean); var v : Variant; begin v := ACellViewInfo.Value;//值 Clipboard.AsText := vartostr(v);

//保存到clipboard end; cxGrid的DBTableView的名称为dgtv1

1. 返回选中的行数 gdtv1.DataController.GetSelectedCount;

2. 返回选中行的索引: gdtv1.DataController.GetSelectedRowIndex(0) , 表示第一个选中行的索引

3. 返回选中行的数据;

var I, J:Integer;

begin

for I:=0 to gdtv1.DataController.GetSelectedCount - 1 do

begin J := gdtv1.DataController.GetSelectedRowIndex(I); ShowMessage(VarToStr(gdtv1.DataController.GetValue(J, 0))); //选择中行的第列的值

end;

end;

4. 获取cxGrid排序规则

const

OrderArray: array[soNone..soDescending] of string = ('None', 'ASC', 'DESC');

var

I: integer;

S, OrderStr: string;

begin

for I := 0 to gdtv1.SortedItemCount - 1 do

begin

if S <> '' then S := S + ', ';

OrderStr := OrderStr + gdtv1.SortedItems[I].DataBinding.DefaultCaption + ' ';

OrderStr := OrderStr + OrderArray[TcxDataSortOrder(gdtv1.SortedItems[I].SortOrder)];

S := S + OrderStr;

end;

ShowMessage('ORDER BY ' + S);

5.获取多选的值

for i := 0 to cxgrid1.SelectedRows.Count-1 do begin

cxgrid1.DataSource.DataSet.GotoBookmark(Pointer(cxgrid1.SelectedRows.Items[i])); //定位选中的字段 end;

6.//选择行的第1列的值

for I:=0 to cxGrid1DBTableView1.DataController.GetSelectedCount - 1 do begin

J := cxGrid1DBTableView1.DataController.GetSelectedRowIndex(I);

ShowMessage(VarToStr(cxGrid1DBTableView1.DataController.GetValue(J, 0))); end;

7.获取所选行的值

with cxGrid1DBTableView1.Controller do

begin

for i:=0 to SelectedRowCount-1 do

begin

SelectedRows[i].Focused:=True;

ShowMessage(ADOQuery1.fieldbyname('mc').AsString);

end;

end

cxGrid功能强大,适合做企业级的复杂查询。非常方便。

但是对其用法介绍的并不多,在此总结他人的使用经验和自己的一点小经验,供大家参考。

(1)动态设置显示格式

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;

(2)显示行号

procedure TFmQueryBase.cxDBViewMasterCustomDrawIndicatorCell(

Sender: TcxGridTableView; ACanvas: TcxCanvas;

AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean);

var

FValue: string;

FBounds: TRect;

begin

FBounds := AViewInfo.Bounds;

if (AViewInfo is TcxGridIndicatorRowItemViewInfo) then

begin

ACanvas.FillRect(FBounds);

ACanvas.DrawComplexFrame(FBounds, clBlack, clBlack, [bBottom, bLeft, bRight], 1);

FValue := IntToStr(TcxGridIndicatorRowItemViewInfo(AViewInfo).GridRecord.Index+1);

InflateRect(FBounds, -3, -2); //Platform specific. May not work on Linux.

ACanvas.Font.Color := clBlack;

ACanvas.Brush.Style := bsClear;

ACanvas.DrawText(FValue, FBounds, cxAlignCenter or cxAlignTop);

ADone := True;

end;

end;

(3)设置显示格式,我的项目要求先动态添加字段,这时不知道字段类型,所以设置DisplayFormat不方便,我还没有找到好方法。

所以采用打开数据集后再设置:

procedure TFmQueryBase.cdsMasterAfterOpen(DataSet: TDataSet);

var

i: Integer;

begin

for i := 0 to cxDBViewMaster.DataController.DataSet.FieldCount -1 do

begin

if cxDBViewMaster.DataController.DataSet.Fields[i] is TNumericField then

begin

if Pos('AMOUNT', UpperCase(cxDBViewMaster.DataController.DataSet.Fields[i].FieldName)) > 0 then

begin

TNumericField(cxDBViewMaster.DataController.DataSet.Fields[i]).DisplayFormat := '#,##0.000';

Continue;

end;

if Pos('QUANTITY', UpperCase(cxDBViewMaster.DataController.DataSet.Fields[i].FieldName)) > 0 then

begin

TNumericField(cxDBViewMaster.DataController.DataSet.Fields[i]).DisplayFormat := '#,##0.000';

Continue;

end;

if Pos('MONEY', UpperCase(cxDBViewMaster.DataController.DataSet.Fields[i].FieldName)) > 0 then

begin

TNumericField(cxDBViewMaster.DataController.DataSet.Fields[i]).DisplayFormat := '#,##0.00';

Continue;

end;

end;

end;

end;

2007-7-19 12:48:54

查看评语&raquo;&raquo;&raquo;

2007-7-19 12:53:09 别人的,转载http://www.showding.cn/item/cxGrid__182526.aspx

最近在学习使用cxGrid,安装的版本是ExpressQuantumGrid Suite v5.10

我发现这个控件功能虽然强大,但是非常难用。

现在我手头就有几个问题还没解决:

1)主从模式下导出Excel中文会产生乱码,而且从表内容没有导出。

我不知道是不是因为我的字段名包括单引号的原因。

导出代码:ExportGrid4ToExcel(FileName, cxGrid);

2)主从模式下通过按钮对从表添加/删除行,代码怎么写。

附:单表添加/删除行的代码

procedure TFormAccount.cxButtonNewClick(Sender: TObject);

begin

Self.tvAccount.DataController.Append;

Self.tvAccount.Columns[0].Focused := True;

cxGrid.SetFocus;

end;

procedure TFormAccount.cxButtonDeleteClick(Sender: TObject);

begin

if Self.tvAccount.DataController.RowCount = 0 then

Exit;

if Application.MessageBox('确认删除当前记录?', '确认删除',

MB_YesNo + MB_IconQuestion) = IDNO then

Exit;

Self.tvAccount.DataController.DeleteFocused;

end;

3)动态创建主从结构出错(Compiler没错,运行时出现系统错误0000000018),

我使用了二个ADOStoreProcedure作主从表

代码如下:

var

Level: TcxGridLevel;

GridView: TcxGridDBTableView;

begin

Level := cxGrid1.Levels[0].Add;

GridView := TcxGridDBTableView(cxGrid1.CreateView(TcxGridDBTableView));

GridView.DataController.DataSource := Self.dsDetail;

GridView.DataController.KeyFieldNames := 'PurchOrderID;POLineNbr;PromiseDate;ReceiverDate';

GridView.DataController.MasterKeyFieldNames := 'VendorID';

GridView.DataController.DetailKeyFieldNames := 'VendorID';

GridView.DataController.DataModeController.SmartRefresh := True;

GridView.OptionsCustomize.ColumnHiding := True;

GridView.OptionsCustomize.ColumnsQuickCustomization := True;

GridView.OptionsData.Deleting := False;

GridView.OptionsData.Inserting := False;

GridView.OptionsView.Indicator := True;

Level.GridView := GridView;

GridView := TcxGridDBTableView(cxGrid1.Levels[0].GridView);

GridView.DataController.KeyFieldNames := 'VendorID';

GridView.OptionsView.GroupByBox := False;

//显示主表内容

tvResult.BeginUpdate;

tvResult.ClearItems;

tvResult.DataController.CreateAllItems;

tvResult.EndUpdate;

//显示明细表内容

GridView := TcxGridDBTableView(cxGrid1.Levels[0].Items[0].GridView);

GridView.BeginUpdate;

GridView.ClearItems;

GridView.DataController.CreateAllItems;

GridView.DataController.Refresh;

GridView.EndUpdate;

end;

技巧二:在内置右键菜单的后面增加菜单项

首先应在Form上加一个cxGridPopupMenu控件 以启用右键菜单

UseBuildInPopupMenus设为True

procedure TFormItemList.FormCreate(Sender: TObject);

var

AMenu: TComponent;

FMenuItem, FSubMenuItem: TMenuItem;

begin

AMenu := nil;

if cxGridPopupMenu.BuiltInPopupMenus.Count = 0 then

Exit;

AMenu := cxGridPopupMenu.BuiltInPopupMenus[0].PopupMenu; //第一个内置右键菜单(表头菜单)

if Assigned(AMenu) and AMenu.InheritsFrom(TPopupMenu) then

begin

TPopupMenu(AMenu).AutoHotkeys := maManual; //手动热键

//-------------------------

FMenuItem := TMenuItem.Create(Self);

FMenuItem.Caption := '-';

FMenuItem.Name := 'miLineForGroup';

TPopupMenu(AMenu).Items.Add(FMenuItem);

//展开所有组

FMenuItem := TMenuItem.Create(Self);

FMenuItem.Name := 'miExpandAllGroup';

FMenuItem.Caption := '展开所有组(&X)';

FMenuItem.OnClick := miExpandAllGroupClick;

TPopupMenu(AMenu).Items.Add(FMenuItem);

//收缩所有组

FMenuItem := TMenuItem.Create(Self);

FMenuItem.Name := 'miCollapseAllGroup';

FMenuItem.Caption := '收缩所有组(&O)';

FMenuItem.OnClick := miCollapseAllGroupClick;

TPopupMenu(AMenu).Items.Add(FMenuItem);

//-------------------------

FMenuItem := TMenuItem.Create(Self);

FMenuItem.Caption := '-';

TPopupMenu(AMenu).Items.Add(FMenuItem);

//过滤面板

FMenuItem := TMenuItem.Create(Self);

FMenuItem.Name := 'miFilterPanel';

FMenuItem.Caption := '过滤面板(&P)';

//自动显示

FSubMenuItem := TMenuItem.Create(Self);

FSubMenuItem.Name := 'miFilterPanelAuto';

FSubMenuItem.Caption := '自动(&A)';

FSubMenuItem.RadioItem := True;

FSubMenuItem.GroupIndex := 5; //指定同一组

FSubMenuItem.Checked := True;

FSubMenuItem.OnClick := miFilterPanelClick;

FMenuItem.Add(FSubMenuItem); //加入二级子菜单

//总是显示

FSubMenuItem := TMenuItem.Create(Self);

FSubMenuItem.Name := 'miFilterPanelAlways';

FSubMenuItem.Caption := '总是显示(&W)';

FSubMenuItem.RadioItem := True;

FSubMenuItem.GroupIndex := 5;

FSubMenuItem.OnClick := miFilterPanelClick;

FMenuItem.Add(FSubMenuItem);

//从不显示

FSubMenuItem := TMenuItem.Create(Self);

FSubMenuItem.Name := 'miFilterPanelNerver';

FSubMenuItem.Caption := '从不显示(&N)';

FSubMenuItem.RadioItem := True;

FSubMenuItem.GroupIndex := 5;

FSubMenuItem.OnClick := miFilterPanelClick;

FMenuItem.Add(FSubMenuItem);

TPopupMenu(AMenu).Items.Add(FMenuItem);

//自定义过滤

FMenuItem := TMenuItem.Create(Self);

FMenuItem.Name := 'miCustomFilter';

FMenuItem.Caption := '自定义过滤(&M)';

FMenuItem.OnClick := miCustomFilterClick;

TPopupMenu(AMenu).Items.Add(FMenuItem);

//过滤管理器

FMenuItem := TMenuItem.Create(Self);

FMenuItem.Name := 'miFilterBuilder';

TPopupMenu(AMenu).Images.AddImage(FormMain.ImageListExtend, 44); //添加图标图像

FMenuItem.ImageIndex := TPopupMenu(AMenu).Images.Count - 1; //指定图标序号

FMenuItem.Caption := '过滤管理器';

FMenuItem.OnClick := Self.miFilterBuilderClick;

TPopupMenu(AMenu).Items.Add(FMenuItem);

//---------------------

FMenuItem := TMenuItem.Create(Self);

FMenuItem.Caption := '-';

TPopupMenu(AMenu).Items.Add(FMenuItem);

//导出

FMenuItem := TMenuItem.Create(Self);

FMenuItem.Name := 'miExport';

TPopupMenu(AMenu).Images.AddImage(FormMain.ImageListExtend, 37);

FMenuItem.ImageIndex := TPopupMenu(AMenu).Images.Count - 1;

FMenuItem.Caption := '导出(&E)';

FMenuItem.OnClick := Self.miExportClick;

TPopupMenu(AMenu).Items.Add(FMenuItem);

//打印

FMenuItem := TMenuItem.Create(Self);

FMenuItem.Name := 'miPrint';

FMenuItem.Caption := '打印(&P)';

TPopupMenu(AMenu).Images.AddImage(FormMain.ImageListExtend, 14);

FMenuItem.ImageIndex := TPopupMenu(AMenu).Images.Count - 1;

FMenuItem.OnClick := Self.miPrintClick;

TPopupMenu(AMenu).Items.Add(FMenuItem);

end;

end;

procedure TFormItemList.miExportClick(Sender: TObject);

var

FileName, FileExt, msg: String;

begin

if Self.aqyQuery.IsEmpty then

begin

msg := '没有导出数据...';

Application.MessageBox(PChar(msg), PChar(Application.Title),

MB_OK or MB_IconWarning);

Exit;

end;

Self.SaveDialogExport.Filter := 'Excel文件 (*.xls)|*.xls|XML文件 (*.xml)|*.xml'

+ '|文本文件 (*.txt)|*.txt|网页文件 (*.html)|*.html';

Self.SaveDialogExport.Title := '导出为';

if not Self.SaveDialogExport.Execute then

Exit;

FileName := Self.SaveDialogExport.FileName;

FileExt := LowerCase(ExtractFileExt(FileName));

if FileExt = '.xls' then

ExportGrid4ToExcel(FileName, Self.cxGrid1)

else if FileExt = '.xml' then

ExportGrid4ToXML(FileName, Self.cxGrid1)

else if FileExt = '.txt' then

ExportGrid4ToText(FileName, Self.cxGrid1)

else if FileExt = '.html' then

ExportGrid4ToHTML(FileName, Self.cxGrid1)

else

begin

msg := '不支持的导出文件类型...';

Application.MessageBox(PChar(msg), PChar(Application.Title),

MB_OK or MB_IconError);

Exit;

end;

msg := '导出完成...';

Application.MessageBox(PChar(msg), PChar(Application.Title),

MB_OK or MB_IconInformation);

end;

procedure TFormItemList.miPrintClick(Sender: TObject);

begin

//打印

Self.dxComponentPrinter.Preview(True, Self.dxComponentPrinterLink1);

end;

procedure TFormItemList.cxGridPopupMenuPopup(ASenderMenu: TComponent;

AHitTest: TcxCustomGridHitTest; X, Y: Integer; var AllowPopup: Boolean);

begin

if GetHitTypeByHitCode(AHitTest.HitTestCode) = gvhtColumnHeader then //右击列标题时

begin

//if tvResult.DataController.Groups.GroupingItemCount > 0 then

if tvResult.GroupedColumnCount > 0 then //有分组时显示

begin

TMenuItem(Self.FindComponent('miLineForGroup')).Visible := True;

TMenuItem(Self.FindComponent('miExpandAllGroup')).Visible := True;

TMenuItem(Self.FindComponent('miCollapseAllGroup')).Visible := True;

end

else

begin

TMenuItem(Self.FindComponent('miLineForGroup')).Visible := False;

TMenuItem(Self.FindComponent('miExpandAllGroup')).Visible := False;

TMenuItem(Self.FindComponent('miCollapseAllGroup')).Visible := False;

end;

end;

end;

procedure TFormItemList.miFilterBuilderClick(Sender: TObject);

begin

//过滤管理器

//弹出Filter Builder Dialog对话框

tvResult.Filtering.RunCustomizeDialog;

end;

procedure TFormItemList.miCustomFilterClick(Sender: TObject);

var

AHitTest: TcxCustomGridHitTest;

begin

//自定义过滤

//弹出Custom Filter Dialog对话框

AHitTest := cxGridPopupMenu.HitTest;

if GetHitTypeByHitCode(AHitTest.HitTestCode) = gvhtColumnHeader then //获得右击的列

tvResult.Filtering.RunCustomizeDialog(TcxGridColumnHeaderHitTest(AHitTest).Column);

end;

procedure TFormItemList.miFilterPanelClick(Sender: TObject);

var

mi: TMenuItem;

begin

//隐藏/显示过滤面板

mi := TMenuItem(Sender);

mi.Checked := True;

if mi.Name = 'miFilterPanelAlways' then

tvResult.Filtering.Visible := fvAlways

else if mi.Name = 'miFilterPanelNerver' then

tvResult.Filtering.Visible := fvNever

else

tvResult.Filtering.Visible := fvNonEmpty;

end;

procedure TFormItemList.miExpandAllGroupClick(Sender: TObject);

begin

//展开所有组

tvResult.DataController.Groups.FullExpand;

end;

procedure TFormItemList.miCollapseAllGroupClick(Sender: TObject);

begin

//收缩所有组

tvResult.DataController.Groups.FullCollapse;

end;

技巧三 按条件计算合计值

在Footer的第一列显示[合计:]

加一个Summary项,Column设为Grid的第一列,Kind设为skNone

在该Summary项的OnGetText事件中,输入:

procedure TFormExpense.tvExpenseTcxGridDBDataControllerTcxDataSummaryFooterSummaryItems2GetText(

Sender: TcxDataSummaryItem; const AValue: Variant; AIsFooter: Boolean;

var AText: String);

begin

AText := '合计:';

end;

按条件汇总:

在TableView的DataController->Summary->FooterSummary->OnSummary事件中,输入:

procedure TFormExpense.tvExpenseDataControllerSummaryFooterSummaryItemsSummary(

ASender: TcxDataSummaryItems; Arguments: TcxSummaryEventArguments;

var OutArguments: TcxSummaryEventOutArguments);

begin

//得到字段名 TcxDBDataSummaryItem(Arguments.SummaryItem).FieldName;

if (ASender.DataController.Values[Arguments.RecordIndex, tvExpenseLevel.Index] > 1) //只统计Level列=1的值

and (TcxDBDataSummaryItem(Arguments.SummaryItem).Kind = skSum) then

OutArguments.Value := 0; //Level > 1的统计值设为0

end;

技巧四:根据某列的值设定其它列的可编辑性

procedure TFormUser.tvUserEditing(Sender: TcxCustomGridTableView;

AItem: TcxCustomGridTableItem; var AAllow: Boolean);

begin

//如果第三列值为True,则第4列不能修改

if (tvUser.Controller.FocusedRecord.Values[2] = True) and (AItem.Index = 4) then

AAllow := False

else

AAllow := True;

end;

技巧五:保存/恢复Grid布局

//恢复布局

IniFileName := ExtractFilePath(Application.ExeName) + 'Layout\' + Self.Name + '.ini';

if FileExists(IniFileName) then

Self.tvResult.RestoreFromIniFile(IniFileName) //从布局文件中恢复

else

begin

Self.tvResult.BeginUpdate;

for i := 0 to Self.tvResult.ItemCount - 1 do

Self.tvResult.Items[i].ApplyBestFit; //调整为最佳宽度

Self.tvResult.EndUpdate;

end;

//保存布局

IniFileName := ExtractFilePath(Application.ExeName) + 'Layout\' + Self.Name + '.ini';

if not DirectoryExists(ExtractFileDir(IniFileName)) then

CreateDir(ExtractFileDir(IniFileName));

Self.tvResult.StoreToIniFile(IniFileName); //保存为布局文件