zoukankan      html  css  js  c++  java
  • Delphi CxGrid 汇总(2)

    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保存/恢复带汇总行的布局解决:
    <TableView>.StoreToIniFile('c:/Grid.ini',   True,   [gsoUseSummary]);    
    <GridView>.RestoreFromIniFile(<inifilename>,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 隐藏 "<No data to display>" 字符串

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

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

    //如果"<No data to display>" 字符串已经显示,需要调用:
    <View>.LayoutChanged;

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

    31 删除应用过滤后的行

    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;

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

    32 根据单元的值设置样式  
    解决:
    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];  
       
    ****************************************************************************
    33 动态生成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;
    end;
    ****************************************************************************
    34 当底层数据集为空时显示一条空记录
    解决:
    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;

  • 相关阅读:
    .NET Core微服务之基于Consul实现服务治理
    在 .NET 4.5 中反射机制的变更
    C#使用Emit构造拦截器动态代理类
    C#使用Emit生成构造函数和属性
    秒懂C#通过Emit动态生成代码
    C# 高性能 TCP 服务的多种实现方式
    Zookeeper的功能以及工作原理
    Eclipse智能提示及快捷键
    【Maven】Select Dependency 无法检索
    springboot的三种启动方式
  • 原文地址:https://www.cnblogs.com/westsoft/p/8504019.html
Copyright © 2011-2022 走看看