關於cxgrid使用的方法收藏


cxGrid控件功能很強大,有許多方法及屬性,其中有一個屬性gridmode

當你設置gridmode=true時,會提高查詢速度,爲false時則反之,爲什麼如此,在網上有相關的貼子

當設置gridmode=true時,則在cxGrid上設置的filtering,sorting,footer中的合計信息均無效(幾天前做一個模塊時發現的)。

我要實現的功能如下:

1.在cxgrid上顯示一些信息(連接數據集很容易實現)

2.每列要有filter的功能(每一列的filtering=true)

3.要有一個合計列(footer,合計的記錄數,數量,金額等)

4.可以選擇部分信息,然後統計更新某一列或幾列的值

其它的還有許多,主要的功能是想把對於Excel操作的相關操作用程序來實現,要達到信息共享,方便統計查詢等但最主要的用程序不能增加工作量(與Excel相比)

在實現過程想了很多辦法為子操作能夠快速簡單,處理過程

1.將一些繁瑣的查詢條件進行分析,然後進行分類,使其簡單化

2.對於複製粘貼等,採用了對像,指針及類似Excel的操作方法實現

3.增加多種條件的篩選及統計,做相關的統計報表避免重複的工作

......

在做的過程中有一個問題,就是在選擇性更新過程中如何刷新使用戶能夠立刻看到結果

第一種方法:

增加刷新的方法,利用update語句來實現更新,然後commit,最後根據選定的條件重新刷新界面,這是我用的比較多的,但目前不方便,刷新後,我看不到我正在更改的是哪條或哪幾條記錄了(如果很多數據)

第二種方法:

利用dataset的edit,post方法進行更新

a.

   for i:= 0 to DSRFTDAVEW.Controller.SelectedRowCount-1 do

   begin

   DSRFTDAVEW.DataController.FocusSelectedRow(i); //這種方法需要設置 gridmode=true,但此時會將filtering,sorting,footer等失效

   oraQuery1.Edit;

   oraQuery1.FieldByName('FeatSN').Value := SerialNO;

   end;

這樣要首先設置gridmode=true,但就會出現最開始提到的問題
我試著在修改時將gridmode=true,當修寇成後再將其gridmode=false,雖然可以修改,但是在修改過程中如果利用某列的filtering先篩選一些數據後,就會出現問題。
b.
利用 DSRFTDAVEW.Controller.FocusedRow := DSRFTDAVEW.Controller.SelectedRows[i]; 來獲取數據的焦點即用cxgridview的controller來實 現,這樣就可以避免gridmode=true的衝突。
下面是在網上找到的相關的資料
2009-03-27 21:31
激活內置編輯控件
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控件實在是太複雜,太龐大,最好的瞭解它的方法就是查幫助。
貼一些小技巧,希望與各位使用cxGrid的朋友共同交流
各位有什麼好個技巧也可以貼出來:
技巧二:在內置右鍵菜單的後面增加菜單項
首先應在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;
此樓回覆Re:
--------------------------------------------------------------------------------
在用,留名
此樓回覆Re:
--------------------------------------------------------------------------------
技巧三 按條件計算合計值
在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;
此樓回覆Re:
--------------------------------------------------------------------------------
借貴地一用,問個CXGrid問題,在cxgrid中如何使一些行不能編輯,如:字段isenable = false的行
此樓回覆Re:
--------------------------------------------------------------------------------
樓上的問題
請參考下面的技巧
技巧四:根據某列的值設定其它列的可編輯性
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;
此樓回覆Re:
--------------------------------------------------------------------------------
技巧五:保存/恢復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); //保存爲佈局文件
此樓回覆Re:
--------------------------------------------------------------------------------
借用地問一下:在 cxgrid中,如果我同時選中主表與子表中的記錄,怎麼樣能同時進行對其所選記錄進行處理呢。
我現在只能判斷 焦點是在主表還是從表中,然後只能對主表或子表中的數據進行處理。
此樓回覆Re:
--------------------------------------------------------------------------------
看來用cxGrid人不多啊
再多貼一些技巧,需要的朋友頂一下
==========================================================================
在主從TableView中根據主TableView得到對應的從TableView
var
ADetailDC: TcxGridDataController;
AView: TcxCustomGridTableView;
begin
with cxGrid1DBTableView1.DataController do
ADetailDC := TcxGridDataController(GetDetailDataController(FocusedRecordIndex, 0));
AView := ADetailDC.GridView;
end;
==============================================================================
定位在第一行並顯示內置編輯器
cxDBVerticalGrid1.FocusedRow := cxDBVerticalGrid1.Rows[0];
cxDBVerticalGrid1.ShowEdit;
==============================================================================
隱藏 "<No data to display>" 字符串
該文本存儲在scxGridNoDataInfoText資源字符串,可以將該資源字符串的內容設爲空
來隱藏該文本。
uses cxClasses, cxGridStrs;
...
cxSetResourceString(@scxGridNoDataInfoText, '');
//如果"<No data to display>" 字符串已經顯示,需要調用:
<View>.LayoutChanged;
============================================================
刪除應用過濾後的行
var
I: Integer;
begin
with <GridView> do
for I := 0 to ViewData.RecordCount - 1 do
begin
ViewData.Records[0].Focused := True;
DataController.DataSet.Delete;
end;
=============================================================
根據單元的值設置樣式
procedure <aForm>.<aColumn>StylesGetContentStyle(
Sender: TcxCustomGridTableView; ARecord: TcxCustomGridRecord;
AItem: TcxCustomGridTableItem; out AStyle: TcxStyle);
begin
if ARecord.Values[AItem.Index] = aSomeValue then
AStyle := <aSomeStyle>;
end;
procedure <aForm>.<aView>StylesGetContentStyle(
Sender: TcxCustomGridTableView; ARecord: TcxCustomGridRecord;
AItem: TcxCustomGridTableItem; out AStyle: TcxStyle);
var
AColumn: TcxCustomGridTableItem;
begin
AColumn := (Sender as TcxGridDBTableView).GetColumnByFieldName('Email');
if VarToStr(ARecord.Values[AColumn.Index]) = '' then
AStyle := cxStyleNullEmail;
end;
==============================================================================
TcxCustomGridTableView.FindItemByName, TcxGridDBTableView.GetColumnByFieldName or
TcxGridDBDataController.GetItemByFieldName
with cxGrid1DBBandedTableView1.DataController do
AValue := Values[FocusedRecordIndex, GetItemByFieldName('SomeFieldName').Index];
===================================================================
動態生成BandedView
var
AView: TcxCustomGridView;
begin
AView := <cxGrid>.CreateView(TcxGridDBBandedTableView);
TcxGridDBBandedTableView(AView).DataController.DataSource := <DataSource>;
TcxGridDBBandedTableView(AView).Bands.Add;
with TcxGridDBBandedTableView(AView).Bands.Add do
begin
Visible := False;
FixedKind := fkLeft;
end;
TcxGridDBBandedTableView(AView).DataController.CreateAllItems;
<cxGridLevel>.GridView := AView;
此樓回覆Re:
--------------------------------------------------------------------------------
======================================================================
當底層數據集爲空時顯示一條空記錄
procedure <Form>.<cxGrid>Enter(Sender: TObject);
var
View: TcxGridDBTableView;
begin
View := TcxGridDBTableView((Sender as TcxGrid).FocusedView);
if View.DataController.DataSet.IsEmpty then
begin
View.DataController.DataSet.Append;
View.Controller.EditingController.ShowEdit;
end;
end;
=======================================================================
在當前View插入記錄
使用FocusedView屬性得到當前焦點View,用View.DataController得到對應的Data Controller,
之後使用Data Controller的方法來操作數據:
- Append
- Insert
- Post
- Cancel
- DeleteFocused
- DeleteSelection
示例:
var
ARecIndex: Integer;

View.DataController.Append;
ARecIndex := View.DataController.FocusedRecordIndex;
View.DataController.Values[ARecIndex, SomeItemIndex] := SomeValue;
View.DataController.Post;
另外一種方法是使用View.DataController.DataSource.DataSet得到底層數據集後,再用數據集的
方法來操作數據。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章