朋友貼給我的,只知道是大陸網站上分享的資料,可在cxGrid內使用CheckBox喔!!!只是用了之後以前可使用 Shift 選區段的功能似乎不能用了。
======================================================================
cxGrid的使用方法
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;
最近在學習使用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;
此樓回復Re:
小技巧:用代碼展開/收縮主從結構
Self.tvDepartment.ViewData.Expand(True);
Self.tvDepartment.ViewData.Collaspe(True);
注:tvDepartment為主表對應的TableView
此樓回復Re:
你說的這幾個問題我也遇到過。
第一個問題是編碼的問題,修改了其中關於編碼的函數,OK.
第二個問題在cxGrid的社區可以找到解答,但從表必須滿足某種條件,例如關鍵字排序。
第三個問題的解決辦法,你可以嘗試在動態創建的代碼前後加上:
grid.beginupdate;
…
grid.endupdate
來解決。
此樓回復Re:
沒用過
不要經常使用三方控制項
此樓回復Re:
to tttk(網路芝麻):
第一個問題:如何修改啊,貼出代碼
第二個問題:沒搜到啊
第三個問題:試一下再說
此樓回復Re:
不要經常使用三方控制項
======================
我感覺不用cxGrid的話,沒必要用Delphi了,呵呵
此樓回復Re:
樓上這話是不是有點問題?DELPHI能做得事情很多很多,難道非要用CXGRID?CXGRID不是用DELPHI做出來得?
此樓回復Re:
沒用過…..
此樓回復Re:
回復人: zxkid(沒有人會像我這樣…) ( ) 信譽:101 2006-01-06 16:58:00 得分: 0
不要經常使用三方控制項
======================
我感覺不用cxGrid的話,沒必要用Delphi了,呵呵
**********
樓主乃天人也!!
此樓回復Re:
呵呵
此樓回復Re:
cxGrid比較不錯,我也使用過導出到Excel,沒有遇到你說的亂碼
主從表也沒有問題的,其實跟單表操作還不是一回事
此樓回復Re:
up
此樓回復Re:
沒用過cxGrid,以後考慮
此樓回復Re:
樓主乃天人也!!
=============================
Delphi下有cxGrid, .NET下有XtraGrid, 它們都是同一公司出的。
遲早都會轉到.NET,所以。。。
此樓回復Re:
路過
此樓回復Re:
用過,挺好,只會使用最簡單的。
此樓回復Re:
發一個郵件給我,我把解決亂碼後的源代碼發一分給你,放到你的專案檔夾下即可。
tttk2000@hotmail.com
此樓回復Re:
第二個問題:https://www.devexpress.com/Support/Center/default.aspx?view=ViewIssue&issueid=B2691
此樓回復Re:
謝謝tttk(網路芝麻)
第二個問題:我現在直接讓用戶用導航條的刪除/添加按鈕了。根據你給的網址上的內容我知道大概該怎么寫了,有空再試試。
第一個問題:不光是亂碼問題,還有從表內容沒導出的問題。
只有一個表的話是不會出現亂碼的。
第三個問題:還沒來得及試。
此樓回復Re:
第一個問題:看了一下幫助,原來cxGrid不支持主從表的導出,只能導出主表(頂層表)的內容。暈
此樓回復Re:
貼一些小技巧,希望與各位使用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得到底層資料集後,再用資料集的
方法來運算元據。
========================================================================
啟動內置編輯控制項
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;
===========================================================================
得到選中記錄的值(MultiSelect)
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) Bkm: string;
View.DataController.DataModeController.GridMode = True時
Bkm := View.DataController.GetSelectedBookmark(ASelectedRecordIndex);
if ADataSet.BookmarkValid(TBookmark(Bkm)) then
begin
ADataSet.Bookmark := Bkm;
OutputVal := ADataSet.FieldByName(AFieldName).Value;
end;
View.BeginUpdate;
View.DataController.BeginLocate;
try
// make changes here…
finally
View.DataController.EndLocate;
View.EndUpdate;
end;
//直接讀取選擇的單格內容
var
I, J: Integer;
val: Variant;
begin
Result := 0;
for I := 0 to TableView.Controller. SelectedRowCount – 1 do
for J := 0 to TableView.Controller. SelectedColumnCount – 1 do
begin
val := TableView.DataController.GetValue(
TableView.Controller.SelectedRows[I].RecordIndex,
TableView.Controller.SelectedColumns[J].Index);
Showmessage(val);
end;
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
每個單號分一個小結,能實現嗎?最後在底下實現總的合計
可以的,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的多選我一般都是用這個方法:
//————— .Pas文件
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, cxStyles, cxCustomData, cxGraphics, cxFilter, cxData, cxEdit,
DB, cxDBData, DBTables, cxGridLevel, cxGridCustomTableView,
cxGridTableView, cxGridDBTableView, cxClasses, cxControls,
cxGridCustomView, cxGrid, cxLookAndFeelPainters, cxGridRows, cxContainer,
cxCheckBox, cxDataStorage;
type
TForm1 = class(TForm)
cxGrid1: TcxGrid;
cxGrid1DBTableView1: TcxGridDBTableView;
cxGrid1DBTableView1CustNo: TcxGridDBColumn;
cxGrid1DBTableView1Company: TcxGridDBColumn;
cxGrid1DBTableView1Addr1: TcxGridDBColumn;
cxGrid1DBTableView1City: TcxGridDBColumn;
cxGrid1DBTableView1State: TcxGridDBColumn;
cxGrid1DBTableView1Country: TcxGridDBColumn;
cxGrid1Level1: TcxGridLevel;
Table1: TTable;
DataSource1: TDataSource;
cxGrid1DBTableView1DBColumn1: TcxGridDBColumn;
procedure FormCreate(Sender: TObject);
procedure cxGrid1DBTableView1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure cxGrid1DBTableView1DBColumn1CustomDrawCell(
Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure cxGrid1DBTableView1CustomDrawCell(
Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
private
AList: TList;
function CheckList(ARecord: TcxCustomGridRecord): Boolean;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
AList := TList.Create;
end;
function TForm1.CheckList(ARecord: TcxCustomGridRecord): Boolean;
begin
Result := AList.IndexOf(Pointer(ARecord.RecordIndex)) <> – 1;
end;
procedure TForm1.cxGrid1DBTableView1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
AHitTest: TcxCustomGridHitTest;
AGridRecord: TcxCustomGridRecord;
begin
if Sender is TcxGridSite then
begin
with TcxGridSite(Sender).GridView do
AHitTest := ViewInfo.GetHitTest(X, Y);
if (AHitTest.HitTestCode = htCell) and (TcxGridDBColumn(TcxGridRecordCellHitTest (AhitTest). Item ). DataBinding . FieldName = ) then
AGridRecord := TcxGridRecordCellHitTest(AHitTest).GridRecord
else
Exit;
end;
if (AGridRecord <> nil) then
if CheckList(AGridRecord) then
AList.Remove(Pointer(AGridRecord.RecordIndex))
else
AList.Add(Pointer(AGridRecord.RecordIndex));
end;
procedure TForm1.cxGrid1DBTableView1DBColumn1CustomDrawCell(
Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
begin
if AViewInfo.EditViewInfo is TcxCustomCheckBoxViewInfo then
TcxCustomCheckBoxViewInfo(AViewInfo.EditViewInfo).State:= TcxCheckBoxState(CheckList(AViewInfo.GridRecord));
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
AList.Free;
end;
procedure TForm1.cxGrid1DBTableView1CustomDrawCell(
Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
begin
with AViewInfo do
if CheckList(GridRecord) then
ACanvas.Brush.Color := clHighlight
else
ACanvas.Brush.Color := clWindow;
ACanvas.Font.Color := clBlack;
end;
end.
//—————cxGrid的Dfm屬性
object cxGrid1: TcxGrid
Left = 0
Top = 0
Width = 688
Height = 446
Align = alClient
TabOrder = 0
object cxGrid1DBTableView1: TcxGridDBTableView
OnMouseDown = cxGrid1DBTableView1MouseDown
NavigatorButtons.ConfirmDelete = False
OnCustomDrawCell = cxGrid1DBTableView1CustomDrawCell
DataController.DataSource = DataSource1
DataController.DetailKeyFieldNames = CustNo
DataController.KeyFieldNames = CustNo
DataController.Summary.DefaultGroupSummaryItems = <>
DataController.Summary.FooterSummaryItems = <>
DataController.Summary.SummaryGroups = <>
OptionsSelection.MultiSelect = True
object cxGrid1DBTableView1CustNo: TcxGridDBColumn
DataBinding.FieldName = CustNo
end
object cxGrid1DBTableView1DBColumn1: TcxGridDBColumn
Caption = CheckColumn
PropertiesClassName = TcxCheckBoxProperties
Properties.DisplayUnchecked = False
OnCustomDrawCell = cxGrid1DBTableView1DBColumn1CustomDrawCell
Options.Editing = False
Options.Filtering = False
Options.IncSearch = False
Options.ShowEditButtons = isebNever
Options.Grouping = False
Options.Sorting = False
Width = 123
end
object cxGrid1DBTableView1Company: TcxGridDBColumn
DataBinding.FieldName = Company
end
object cxGrid1DBTableView1Addr1: TcxGridDBColumn
DataBinding.FieldName = Addr1
end
object cxGrid1DBTableView1City: TcxGridDBColumn
DataBinding.FieldName = City
end
object cxGrid1DBTableView1State: TcxGridDBColumn
DataBinding.FieldName = State
end
object cxGrid1DBTableView1Country: TcxGridDBColumn
DataBinding.FieldName = Country
end
end
object cxGrid1Level1: TcxGridLevel
GridView = cxGrid1DBTableView1
end
end
cyblueboy83 發表於 2005-12-9 11:30:45
學習
hanlin2004 發表於 2005-12-9 13:14:52
我一般是這樣取cxGrid選中的紀錄的值的:
function TFrameAccount.GetSelectedID:variant;
var
AccID: array of string;
i, n: Integer;
Index: Integer;
begin
n := cxGrid1DBTableView1.DataController.GetSelectedCount;
for i:=0 to n – 1 do
begin
Index := cxGrid1DBTableView1.DataController.GetSelectedRowIndex(i);
setlength(AccID, length(AccID) + 1);
AccID[High(AccID)] :=cxGrid1DBTableView1.DataController.GetRowValue(cxGrid1DBTableView1.DataController.GetRowInfo(Index),0); //這裏的0是Grid中列的索引,0表示第一個列綁定的欄位
end;
result := AccID;
end;
DevExpress cxGrid的應用
在cxGrid下建立view,取名myView
1. 允許選擇多條記錄(MultiSelect):
myView–OptionsSelection–MultiSelect 設成true
2. 取得選定行的值:
myView->DataController->FocusedRowIndex 獲得選擇行的行號
myView->DataController->Values[myView->DataController->FocusedRowIndex+1][0] 選擇的行的第一列的值
myView->DataController->GetSelectedCount() 選擇多行的行數
myView->DataController->GetSelectedRowIndex(行號n) 所選多行裏的第n行
3. VerticalGrid的單元值
控制項->Properties->Value 獲得單元的值,此值為variant類型,需要強制轉換成AnsiString
4. VerticalGrid裏的CheckGroup的使用
得到的值為: (;1,3,8)此為選擇了選項裏的第1、3、8項
5. VerticalGrid裏驗證
TcxEditorRow的properties->EditorProperties選MaskEdit,然後再選下面的MaskEdit和MaskKind,可以限定輸入的東西
6. TcxPopupEdit控制項的應用,Form1加一個控制項cxPopupEdit1
屬性裏PopupControl指向你要彈出的表單Form2,Form2裏添加一個按鈕,說明文件裏添加
CODE:
private: // User declarations
AnsiString FEditValue;
TcxPopupEdit *FPopupEdit;
。。。
public:
__property AnsiString EditValue = {read=FEditValue,write=FEditValue};
__property TcxPopupEdit *PopupEdit = {read=FPopupEdit, write=FPopupEdit};
在Form1的cxPopupEdit1控制項的事件裏添加下面的代碼
CODE:
//—————————————————————————
void __fastcall TForm1::cxPopupEdit1PropertiesInitPopup(TObject *Sender)
{
Form2->PopupEdit = (TcxPopupEdit*)Sender;
}
//—————————————————————————
void __fastcall TForm1::cxPopupEdit1PropertiesCloseUp(TObject *Sender)
{
cxPopupEdit1->EditValue = Form2->EditValue;
}
在Form1的按鈕事件裏可以加入
CODE:
FEditValue = "嘻嘻哈哈";
FAccepted = AAccepted;
FPopupEdit->DroppedDown = false;
//—————————————————————————
7. TcxGrid控制項去掉上面的"Drag a column header here to group by that column"欄
在控制項的view的OptionsView屬性裏有一個GroupByBox,設為false即可
呵呵,寫的有些亂,自己試著做吧
選擇了若干條記錄(MultiSelect)
選擇了若干條記錄(MultiSelect),現在要把這些選中的記錄從該資料庫複製到另一庫中,該如何做?
可以參考。我的程式是列印選擇的記錄 ,
你可以保存到其他表就好。
var i:integer;
begin
if cxview1.DataController.Controller.SelectedRecordCount>0 then
with cxview1.DataController.DataSource.DataSet do
begin
global.BQ_ppp(”,3); //只進行資料清除
for i:=0 to cxview1.DataController.Controller.SelectedRecordCount-1 do
begin
GotoBookmark(Pointer(cxview1.DataController.GetSelectedBookmark(i)));
if Pos(‘計’,fields[0].AsString)=0 then
begin
if CheckBox2.Checked then
global.BQ_ppp(fields[0].AsString,0)//立即進行標籤列印,不把資料加到臨時資料庫。
else
global.BQ_ppp(fields[0].AsString,1); //加入資料到臨時資料庫。
end;
end;
if CheckBox2.Checked=false then //列印中的資料只是包含一種標籤。 不是多種標籤列印,集中列印臨時資料庫中的資料。
global.BQ_ppp(”,2); //只進行標籤列印
Log_save(‘標籤補打’,’標籤列印’);
end;
end;
來自:lihoulong, 時間:2006-7-8 23:59:31, ID:3500034
function CopyRecord(var recData: TArrayVariant): boolean;
var
i: integer;
begin
with FDataset do
begin
SetLength(recData, Fields.Count);
for i := 0 to Fields.Count – 1 do
recData[i] := Fields[i].Value;
end;
Result := true;
end;
function TwpQDTable.PasteRecord(
const RecData: array of Variant): boolean;
var
fcnt,
i: integer;
begin
with FDataset do
try
fcnt := Length(RecData) – 1;
for i := 0 to fcnt do
begin
if FDataset.State in [dsBrowse] then
Edit;
Fields[i].Value := RecData[i];
end;
Result := true;
except
Result := false;
end;
end;
定義一個記錄陣列
for i := 0 to cxgrid.SelectedCount-1 do begin
依據關鍵字定位資料集,再執行CopyRecord
end;
在粘貼的地方用pasteRecord
cxGrid的使用方法
1. 去掉cxgrid中台頭的box ,在tableview1的ptionsview的groupbybox=false;
2. 在GRID footer 中加入sum(列), tableview1的optionsviewàfooter=ture
然後在cxGRid1的customize..中的summary 的footer.add需要合計的列kind= skSum
3. 去掉cxgrid 中的過濾下拉箭頭 選擇tableview1.optionscustomize.columnfiltering=fasle;
4. cxGrid1DBTableView1 的 OptionView中屬性GroupFooters設為gfAlwaysVisible並設置需要求和的列,在summary.default for Groups 下add加入需要合計的欄位,column下顯示fieldname 為統計欄位,format為格式,kind為統計方法,position 為位子 spfooter 在分組的下面,spgroup 在分組的上面
或用cxGridPopupMenu1,在運行時可對任意數字類型列求和,方法是只需設置cxGridPopupMenu1的屬性Grid為cxGrid1DBTableView1的cxGrid,
即可實現您所需功能
5. DEV Express裏的cxGrid默認的數值格式帶¥,怎么去掉啊!
6. 雙擊Cxgrid,選擇colmnum改變類型 options.properties.Memo
7. 在displayformat中進行設置
來源於大富翁論壇
使用cxGrid有一些時間了,在這裏總結一下使用cxGrid的一些方法,希望給剛開始接觸cxGrid的人一些幫助。
1.簡單介紹:cxGrid右下方的cxGrid1Level1是表示Grid表的層,cxGrid可以有多層,這相當於集合了PageControl的
功能,而cxGrid1Level1右邊的cxGrid1DBTableView1相當於DBGrid一樣。右擊cxGrid1可以添加cxGrid1Level2,右擊
cxGrid1Level2,可以選擇Create View , Add level 或者Delete Level。Add level可以增加子Level,Create View
裏面可以選擇很多不同總類的View。其中
1)DB Table可以和資料庫連接的View,更一般的DBGrid類似,它比DBGrid多了比如滑鼠中鍵可以用,可以統計,
查詢,等等功能;
2)DB Banded Table 則可以實現比如:
———————————
| 說明1 | 說明2 |
———————————
| 欄位1 | 欄位2 | 欄位3 | 欄位4 |
等類似的功能;
3)DB Card View 則提供了卡片方式的顯示資料的功能,這個用在比如人事檔案管理比較不錯;
4)其他不一一贅述。
2.一些使用方法:
1)有圖片和MEMO的例子:
拖入一個cxGrid1,Table1,DataSource1。 Table1的DatabaseName設為DBDEMOS,TableName設為biolife.db,
Active設為True;DataSource1的DataSet設為Table1;cxGrid1DBTableView1的DataController中的DataSource
設為DataSource1;右擊cxGrid1DBTableView1選擇Create All Columns;雙擊cxGrid1,在彈出的窗口中找到
cxGrid1DBTableView1Notes和cxGrid1DBTableView1Graphic,將它們的Properties屬性設為BlobEdit;運行看看
結果。再將cxGrid1DBTableView1Graphic的Properties屬性設為Image,再將Properties下的Stretch設為True,
將cxGrid1DBTableView1->optionsview->CellAutoHeight 設為True,看看結果。
2)如何讓“Drag a column here to group by that column”不顯示
解決:點擊cxGrid1上的cxGrid1DBTableView1
在cxGrid1DBTableView1->optionsview->groupbybox:=false即可
注:OptionsView裏面有很多屬性可能經常要用,比如:ColumnAutoWith,Navigator等等,慢慢琢磨吧:)
3)GroupPanel上面的英文[Drag a column header to group by that column]怎么可以改成中文?
解決:最簡單的方法是 TcxGridTableView.OnCustomDrawPartBackground ,也可用 OnCustomDrawGroupCell:
procedure TForm1.cxGrid1DBTableView1CustomDrawPartBackground(
Sender: TcxGridTableView; ACanvas: TcxCanvas;
AViewInfo: TcxCustomGridCellViewInfo; var ADone: Boolean);
begin
AViewInfo.Text:=’動態設置 GroupBox 的顯示內容’;
ACanvas.FillRect(AViewInfo.Bounds);
end;
4)如何實現如下功能:
+財務部
+原材料倉庫
+成品庫
+衝壓車間
+軟體發展部
這個是部門的名稱,點擊加號就可以將本部門的人員情況顯示出來。
解決:其實這是一個主從表關係,1:填好主表的keyfieldnames
2:填好從表的keyfieldnames
3:填好從表的 detaikeyfieldNames與masterkeyfieldnames
4: 從表的資料源一定要按與主表關聯的欄位排序
注:其他地方設置了主從表結構那樣就顯示不出來,比如設置了從表的Table或者Query的mastersource和
asterfield就會不能顯示資料!如果是兩個cxGrid的主從關係,這樣設置就很OK了。
5)統計功能
解決:cxGrid1DBTableView1->optionsview->Footer 設為True
cxGrid1DBTableView1->DataController->Summary設置FooterSummaryItems即可
6)類似PageControl顯示
解決:增加一個Level,將cxGrid1->RootLevelOptions->DetailTabsPosition設為dtpTop,然後相應的設置cxGrid1Level1,和cxGrid1Level2的Caption值。
未完待續。。。。。。。。。
7)如何設定左邊幾列,不能滾動?
解決:使用DB Banded Table才可以實現,
在cxGrid1DBBandedTableView裏建立Band0,Band1
Band0的Fixed=tfLeft
Band1的Fixed=tfnone
設置要鎖定的欄位的BandIndex=0,其他為1,就OK了。
8)怎樣實現如EXCEL一樣的,當前格=G14+G15+G16 這樣的功能
解決:舉一個簡單的例子:label1.Caption := cxGrid1DBTableView1.DataController.Values[2,
3]+cxGrid1DBTableView2.DataController.Values[1, 1]+cxGrid1DBTableView3.DataController.Values[1, 1];
所以不同cxGrid1DBTableView中的資料都可以給當前格,這樣就做到了EXCEL中的當前格=G14+G15+G16 類似的功能。
9)滑鼠右擊cxGrid1DBBandedTableView1功能表裏的Edit Layout什么用,怎么使用?
解決:可以拖動欄位,並列的可以拖成有層次感(一層層), 拖動時會顯示箭頭的,就是說可以拖一個欄位放
到最上面,就可以使記錄按此欄位進行分組。點擊其中一個欄位,上面還會出現一個上升或者下降的小三角形,這個
小三角形的作用是在運行階段,資料就會按照這個欄位上升或者下降排序。
還有一個Set as Default的作用是保持當前TableView的參數,下此產生新的TableView的時候就會可以和上次保持的參數一樣。這個還沒有做過試驗。
10)怎樣將cxGrid裏的數據導入到EXCEL,HTML,XML和TEXT
解決:這個問題在用了cxGrid以後變得異常簡單,
uses
cxExportGrid4Link;
procedure TForm1.Button1Click(Sender: TObject);
begin
ExportGrid4ToEXCEL(‘d:\wang.xsl’,cxGrid1,True,True);
ExportGrid4ToTEXT(‘d:\wang.txt’,cxGrid1,True,True);
ExportGrid4ToXML(‘d:\wang.xml’,cxGrid1,True,True);
ExportGrid4ToHTML(‘d:\wang.html’,cxGrid1,True,True);
end;
11)如何使滿足條件的資料顯示不同的顏色?
解決:
var
AYellowStyle: TcxStyle;
procedure TForm1.FormCreate(Sender: TObject);
begin
//行顏色
AYellowStyle := TcxStyle.Create(Self);
AYellowStyle.Color := $0080FFFF;
AYellowStyle.TextColor := clMaroon;
end;
procedure TForm1.cxGrid1DBBandedTableView1StylesGetContentStyle(
Sender: TcxCustomGridTableView; ARecord: TcxCustomGridRecord;
AItem: TcxCustomGridTableItem; out AStyle: TcxStyle);
begin
if ARecord.Values[cxGrid1DBBandedTableView1Lengthcm.Index] < 81 then
AStyle := AYellowStyle;
end;
這裏cxGrid1DBBandedTableView1Lengthcm.Index小於81時就顯示黃色
12)如何從外邊的TXT文件導入到cxGrid?
解決: procedure CustomizeColumns;
procedure LoadData;
procedure TForm1.CustomizeColumns;
const
cDistance = 1;
cRadius = 5;
cPeriod = 4;
cPstring = 0;
var
I: Integer;
begin
DecimalSeparator := ‘.’;
with cxGrid1TableView2 do
for I := 0 to ColumnCount – 1 do
if I in [cDistance, cRadius] then
Columns[I].DataBinding.ValueTypeClass := TcxIntegerValueType//1,5列為Integer
else
if I in [cPstring,cPeriod] then
Columns[I].DataBinding.ValueTypeClass := TcxStringValueType//0,4列為String
else
Columns[I].DataBinding.ValueTypeClass := TcxFloatValueType;//其他為Float
end;
procedure TForm1.LoadData;
const
AFileName = ‘資產負債表.txt’;
AHeaderLineCount = 2;
var
ARecords, AValues: TStringList;
I: Integer;
procedure InitRecord(const Str: string);
var
J: Integer;
V: Variant;
begin
AValues.CommaText := Str;
for J := 0 to AValues.Count – 1 do
if AValues.Strings[J] <> ‘-‘ then
begin
V := AValues.Strings[J];
if not VarIsNull(V) then
cxGrid1TableView2.DataController.Values[I, J] := V;
end;
end;
begin
if not FileExists(AFileName) then
raise Exception.Create(‘Data file not found’);
ARecords := TStringList.Create;
AValues := TStringList.Create;
with ARecords do
try
LoadFromFile(AFileName);
cxGrid1TableView2.BeginUpdate;
cxGrid1TableView2.DataController.RecordCount := Count – AHeaderLineCount;
for I := 0 to Count – (AHeaderLineCount + 1) do
InitRecord(Strings[I + AHeaderLineCount]);
finally
cxGrid1TableView2.EndUpdate;
ARecords.Free;
AValues.Free;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
CustomizeColumns;
LoadData_Zcfz;
end;
13)如何改變列的顏色?
var
AFirstColumnStyle: TcxStyle;
procedure TForm1.FormCreate(Sender: TObject);
begin
//列顏色
AFirstColumnStyle := TcxStyle.Create(Self);
AFirstColumnStyle.Color := clAqua;
AFirstColumnStyle.TextColor := clBlue;
cxGrid1TableView1.Columns[1].Styles.Content := AFirstColumnStyle;
end;
14)Set as default的用法?
解決:Set as default的用法是為了解決設置參數的方便而做的,比如:
連好資料庫以後,更改cxGrid1DBBandedTableView1->OptionsCustomize->ColumnFiltering 設為False。(這個設置可以將欄位名的下拉單給去掉)更改cxGrid1DBBandedTableView1->OptionsView->Navigator 設置為True。然後右擊cxGrid1DBBandedTableView1,在彈出的菜單欄裏麵點擊Set as default。
OK,下次你再產生一個新的cxGrid1DBBandedTableView1時這些設置和剛才的一樣了。如果需要設置的參數很多的時候,這個Set as default很有用!
15)怎樣使滑鼠移動時,相應的單元裏的文字變色?
解決:
var
FTrackItem: TcxCustomGridTableItem;
FTrackRec: TcxCustomGridRecord;
procedure TForm1.cxGrid1DBTableView1CustomDrawCell(
Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
begin
if (AViewInfo.GridRecord = FTrackRec) and (AViewInfo.Item = FTrackItem) then
begin
ACanvas.Font.Color := clred; //紅色字體
ACanvas.Font.Style := [fsUnderline];//帶下劃線
end;
end;
procedure TForm1.cxGrid1DBTableView1MouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);
var
AHitTest: TcxCustomGridHitTest;
ATrackItem: TcxCustomGridTableItem;
ATrackRec: TcxCustomGridRecord;
begin
ATrackItem := FTrackItem;
ATrackRec := FTrackRec;
AHitTest := (Sender as TcxGridSite).GridView.ViewInfo.GetHitTest(X, Y);
if AHitTest is TcxGridRecordCellHitTest then
begin
FTrackItem := TcxGridRecordCellHitTest(AHitTest).Item;
FTrackRec := TcxGridRecordCellHitTest(AHitTest).GridRecord;
end
else
begin
FTrackItem := nil;
FTrackRec := nil;
end;
if (ATrackItem <> FTrackItem) or (ATrackRec <> FTrackRec) then
begin
// Invalidate old cell
if ATrackRec <> nil then
ATrackRec.Invalidate(ATrackItem);
// Invalidate new cell
if FTrackRec <> nil then
FTrackRec.Invalidate(FTrackItem);
end;
end;
16)ExpressQuantumGrid 3.2.2中的dxdbgrid和4.2版本中的cxgrid有什么區別?
有很大的區別,基本上相當於是兩個控制項一樣。
cxgrid是在dxdbgrid基礎上完全重寫的,所以cxgrid不支持dxdbgrid
所以cxgrid裏面特意提供了一個將dxdbgrid導入到cxgrid的功能。
17)怎樣設計多表頭的cxGrid?
解決:cxGrid可以解決如下的表頭:
———————————
| 說明1 | 說明2 |
———————————
| 欄位1 | 欄位2 | 欄位3 | 欄位4 |
| 欄位5 | 欄位6 |
| 欄位7 | 欄位8 | 欄位9 |
實現這個很簡單,你可以直接在上面拖動欄位名,拖動時會顯示箭頭的,放入你想顯示的位置就OK了。或者在滑鼠右擊cxGrid1DBBandedTableView1功能表裏的Edit Layout裏也可以拖放。
但是cxGrid不能實現如下的多表頭形式:
———————————
| 說明1 | 說明2 |
———————————
| 說明3 | 說明4 | 說明5 | 說明6 |
| 欄位1 | 欄位2 |
| 欄位3 | 欄位4 | 欄位5 |
不知道有誰能實現這樣的多表頭?
18)在主從表結構時,當點開“+”時怎樣將焦點聚在相應主表的記錄上?
解決:
var
HitTest: TcxCustomGridHitTest;
procedure TColumnsShareDemoMainForm.tvProjectsMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
// Note that the Sender parameter is a Site
HitTest := (Sender as TcxGridSite).GridView.ViewInfo.GetHitTest(X, Y);
// The point belongs to the [+]/[-] button area
if HitTest is TcxGridExpandButtonHitTest then
// Move focus to the record
TcxGridExpandButtonHitTest(HitTest).GridRecord.Focused := True;
end;
19)CXGrid4如何展開全部節點
解決:GridDBTableView1.DataController.Groups.FullExpand;
2003-12-12 17:07:30 問題20
20)cxGrid如何動態創建Items的Editor的項?
cxGrid的列有一個屬性,它的編輯框可以指定combobox,spinedit等.在設計時,可以為
combobox的items添加項目.請問是否可以動態創建?(run-time時由程式加入)
解決:
var
A:TDataSource:
B:TcxlookupcomboboxProperties;
begin
A:=TDataSource.create(self);
B:=tcxlookupcomboboxproperties.create(self);
A.Dataset:=Dic_ry_xb;//此處指定數據源。
b.listdource:=a;//此處指明欄位的listsource屬性。
b.keyfieldnames:=’a’; //此處指明欄位的關鍵字段
b.listfieldnames:=’b’; //此處指明欄位的返回值。
b.listcolumns.items[0].caption:=’x; //此處默認是會建立一個欄位,但是顯示的表頭是name,所以此處讓它顯示為自己想要的中午顯示。
cxGrid1DBTableView1c1_sex_code.Properties:=b; //此處指明是那個欄位。
end; //這個是初始化的代碼,
2004-1-7 14:05:14 問題21
21)ExpressQuantumGrid4.5的漢化包
在這裏可以下載ExpressQuantumGrid4.5的漢化包,將檔直接覆蓋到原始檔案就可以了。
如何在dxMemData1或cxGrid1中動態添加欄位?
Procedure TcxGridDBTableView.CreateDefaultColumn; //建立默認的列 //Add By Pgt
Var
CxColumn:TcxGridDBColumn;
FootItem:TcxDataSummaryItem;
i:Integer;
OldAutoWidth:Boolean;
Begin
If Assigned(DataController.DataSource) And
Assigned(DataController.DataSource.DataSet) And
DataController.DataSource.DataSet.Active Then Begin
With DataController.DataSource.DataSet Do Begin
While ColumnCount>0 Do
Columns[0].Free ;
For i:=0 to FieldCount -1 Do Begin
If (Fields[i].DataType<>ftAutoInc) And (UpperCase(Fields[i].FullName)<>’ID’) Then Begin
CxColumn:=Self.CreateColumn ;
CxColumn.DataBinding.FieldName := Fields[i].FullName ;
CxColumn.HeaderAlignmentHorz := taCenter ;
CxColumn.HeaderAlignmentVert := VaCenter ;
If CxColumn.Width >150 Then CxColumn.Width := 150 ;
If i=0 Then Begin
FootItem := DataController.Summary.FooterSummaryItems.Add ;
FootItem.ItemLink :=CxColumn ;
FootItem.Format := ‘共0條’;
FootItem.Kind := skCount ;
End Else Begin
If (Fields[i].DataType = ftFloat) And (Pos(‘價’,Fields[i].FullName)=0) Then Begin
FootItem := DataController.Summary.FooterSummaryItems.Add ;
FootItem.ItemLink :=CxColumn ;
If Pos(‘數量’,Fields[i].FullName)<>0 Then
FootItem.Format := ‘,0;-,0’
Else Begin
FootItem.Format := ‘,0.00;-,0.00’ ; // ‘¥,0.00;-¥,0.00’;
If CxColumn.Width<80 Then CxColumn.Width := 80 ;
End;
FootItem.DisplayName := Fields[i].FullName ;
FootItem.Kind := skSum ;
End;
End;
End;
End;
OldAutoWidth := Self.OptionsView.ColumnAutoWidth ;
Self.OptionsView.ColumnAutoWidth := True ;
Self.OptionsView.ColumnAutoWidth := OldAutoWidth ;
End;
End;
End;
近期留言