Delphi CxGrid 汇总(2)

2021-02-11 10:17

阅读:604

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;

****************************************************************************
20. cxGrid如何动态创建Items的Editor的项?
解决:cxGrid的列有一个属性,它的编辑框可以指定combobox,spinedit等.在设计时,可以为
combobox的items添加项目.请问是否可以动态创建?(run-time时由程序加入)

[delphi] view plaincopy
 
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; //这个是初始化的代码  

 

 

****************************************************************************
21. 拷贝文件时有进度显示
解决:

[delphi] view plaincopy
 
procedure TForm1.mycopyfile(sourcef,targetf:string);  
var  
FromF, ToF: file;  
NumRead, NumWritten: Integer;  
Buf: array[1..2048] of Char;  
n:integer;  
begin  
   AssignFile(FromF, sourcef);  
   Reset(FromF, 1); { Record size = 1 }  
   AssignFile(ToF,targetf); { Open output file }  
   Rewrite(ToF, 1); { Record size = 1 }  
   n:=0;  
   repeat  
        BlockRead(FromF, Buf, SizeOf(Buf), NumRead);  
        form1.label1.caption:=IntToStr(sizeof(buf)*n*100 div FileSize(FromF))+100%;  
        application.ProcessMessages;  
        //显示进度  
        BlockWrite(ToF, Buf, NumRead, NumWritten);  
        inc(n);  
    until (NumRead = 0) or (NumWritten  NumRead);  
    form1.Label1.Caption:=100%;  
    CloseFile(FromF);  
    CloseFile(ToF);  
end;  
procedure TForm1.Button1Click(Sender: TObject);  
begin  
mycopyfile(e:/components/tv2k-w2k.zip,c:/a.zip);  
end;  

 

****************************************************************************
22. cxGrid 设置斑马线
解决:
在TcxGridDBBandedTableView.Styles属性中有 ContentEven(奇数行风格) ContentOdd (偶数行风格) ,设定一下风格就好了。
****************************************************************************
23 根据记录内容更改字体颜色
解决:
参考范例CustomDrawTableViewDemo,
主要在TcxGridDBBandedTableView.OnCustomDrawCell事件中实现。
如下代码:

if   (Pos(‘-‘,AViewInfo.GridRecord.DisplayTexts[colOrderProductCount.Index]) > 0) then
begin //标识负数记录
    //ACanvas.Canvas.Brush.Color:= clMoneyGreen;
    ACanvas.Canvas.Font.Color:= clRed;//clActiveCaption
end;

其中colOrderProductCount是“产品订数”列。

还要有一步就是要刷新显示

TcxGridDBBandedTableView.LayoutChanged();
//tvCars.LayoutChanged(False);
TcxGridDBBandedTableView.Painter.Invalidate;

****************************************************************************
24 用代码展开/收缩主从结构
解决:
      Self.tvDepartment.ViewData.Expand(True);  
      Self.tvDepartment.ViewData.Collaspe(True);  
注:tvDepartment为主表对应的TableView

****************************************************************************
25 在内置右键菜单的后面增加菜单项
解决:
首先应在Form上加一个cxGridPopupMenu控件   以启用右键菜单  
UseBuildInPopupMenus设为True  

[delphi] view plaincopy 
  1. 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;  

     

****************************************************************************
26 根据某列的值设定其它列的可编辑性
解决:
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;

****************************************************************************
27 保存/恢复Grid布局
解决:
网格左上角的自定义布局按钮:
TableView-?OptionsCustiomize?ColumnsQuickCustomization true;

[delphi] view plaincopy
 
  1. //恢复布局    
    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); //保存为布局文件  
      
      
    实例:  
    IniFileName: string;  
      
    procedure TMainFM.FormCreate(Sender: TObject);     //窗体创建时读取布局  
    var i: Integer;  
    begin  
       qyHed.Open;  
       IniFileName := ExtractFilePath(Application.ExeName) + /Layout/ + cxGrd.Owner.ClassName + cxGrd.Name + .ini;  
       if FileExists(IniFileName) then  
          Self.cxTbv.RestoreFromIniFile(IniFileName) //从布局文件中恢复  
       else  
       begin  
          Self.cxTbv.BeginUpdate;  
          for i := 0 to Self.cxTbv.ItemCount - 1 do  
             Self.cxTbv.Items[i].ApplyBestFit; //调整为最佳宽度  
          Self.cxTbv.EndUpdate;  
       end;  
    end;  
      
    procedure TMainFM.NSaveGrdClick(Sender: TObject);      //保存布局文件  
    begin  
       try  
          IniFileName := ExtractFilePath(Application.ExeName) + /Layout/ + cxGrd.Owner.ClassName + cxGrd.Name + .ini;  
          if not DirectoryExists(ExtractFileDir(IniFileName)) then  
             CreateDir(ExtractFileDir(IniFileName));  
          Self.cxTbv.StoreToIniFile(IniFileName);  
       except  
       end;  
    end;  

     

****************************************************************************

28保存/恢复带汇总行的布局解决:
.StoreToIniFile(‘c:/Grid.ini‘,   True,   [gsoUseSummary]);    
.RestoreFromIniFile(,True,False{or True,optional},[gsoUseSummary]);

 zj:本条与50条重复

****************************************************************************

28 在主从TableView中根据主TableView得到对应的从TableView
解决:

var  
      ADetailDC:   TcxGridDataController;  
      AView:   TcxCustomGridTableView;  
begin  
      with   cxGrid1DBTableView1.DataController   do  
          ADetailDC   :=   TcxGridDataController(GetDetailDataController(FocusedRecordIndex,   0));  
      AView   :=   ADetailDC.GridView;  
end;

 

==============================================================================

29 定位在第一行并显示内置编辑器

cxDBVerticalGrid1.FocusedRow := cxDBVerticalGrid1.Rows[0];
cxDBVerticalGrid1.ShowEdit;

==============================================================================

30 隐藏 "" 字符串

该文本存储在scxGridNoDataInfoText资源字符串,可以将该资源字符串的内容设为空
来隐藏该文本。

uses cxClasses, cxGridStrs;
...
cxSetResourceString(@scxGridNoDataInfoText, ‘‘);

//如果"" 字符串已经显示,需要调用:
.LayoutChanged;

============================================================

31 删除应用过滤后的行

var
I: Integer;
begin
with do
for I := 0 to ViewData.RecordCount - 1 do
begin
ViewData.Records[0].Focused := True;
DataController.DataSet.Delete;
end;

============================================================= 
 

32 根据单元的值设置样式  
解决:
procedure   .StylesGetContentStyle(  
      Sender:   TcxCustomGridTableView;   ARecord:   TcxCustomGridRecord;  
      AItem:   TcxCustomGridTableItem;   out   AStyle:   TcxStyle);  
begin  
      if   ARecord.Values[AItem.Index]   =   aSomeValue   then  
          AStyle   :=   ;  
end;  
   
procedure   .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];  
   
****************************************************************************
33 动态生成BandedView
解决:
var  
      AView:   TcxCustomGridView;  
begin  
      AView   :=   .CreateView(TcxGridDBBandedTableView);  
      TcxGridDBBandedTableView(AView).DataController.DataSource   :=   ;  
      TcxGridDBBandedTableView(AView).Bands.Add;  
      with   TcxGridDBBandedTableView(AView).Bands.Add   do  
      begin  
          Visible   :=   False;  
          FixedKind   :=   fkLeft;  
      end;  
      TcxGridDBBandedTableView(AView).DataController.CreateAllItems;  
      .GridView   :=   AView;
end;
****************************************************************************
34 当底层数据集为空时显示一条空记录
解决:
procedure  

.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;


评论


亲,登录后才可以留言!