打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
delphi中cxGrid使用汇总(二) (转)

delphi中cxGrid使用汇总(二) (转)  

2011-12-27 22:05:14|  分类: delphi |字号 订阅

50 保存/恢复带汇总行的布局

<TableView>.StoreToIniFile('c:\Grid.ini', True, [gsoUseSummary]);
<GridView>.RestoreFromIniFile(<inifilename>,True,False {or True, optional},[gsoUseSummary]);

 

****************************************************************************
51 取消过滤时移到第一行
解决:
uses 
      cxCustomData; 
  
procedure   TYour_Form.AViewDataControllerFilterChanged(Sender:   TObject); 
var 
      Filter:   TcxDataFilterCriteria; 
begin 
      with   Sender   as   TcxDataFilterCriteria   do 
          if   IsEmpty   then 
              DataController.FocusedRowIndex   :=   0; 
end;
****************************************************************************
52 排序后移到第一行
解决:
可以设置DataController.Options.FocusTopRowAfterSorting   :=   True,也可以使用如下的代码: 
  
uses 
      cxCustomData; 
  
procedure   TYour_Form.Your_ViewDataControllerSortingChanged(Sender:   TObject); 
begin 
      TcxCustomDataController(Sender).FocusedRowIndex   :=   0; 
end;
****************************************************************************
53 判断当前行是否第一行或最后一行
解决:
可以使用DataController的IsBOF,   IsEOF方法,或者: 
<AView>.Controller.Controller.FocusedRow.IsFirst 
<AView>.Controller.Controller.FocusedRow.IsLast
****************************************************************************
54 根据指定值查找记录
解决:
DataController提供了好几个方法来得到指定值对应的RecordIndex 
对于Bound   View可以使用FindRecordIndexByKeyValue方法
****************************************************************************
55 编辑和显示Blob字段
解决:
该字段的Properties设置为BlobEdit,并将BlobPaintStyle   属性设为   bpsText
****************************************************************************
56 得到可见行数
解决:
<View>.ViewInfo.VisibleRecordCount
****************************************************************************
57 保存后的行设置为当前行
解决:
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.
****************************************************************************
58 删除记录并获得焦点
解决:
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;
****************************************************************************
59 cxGrid的 TableView 数据排序与对应的数据集同步
解决:
COPYRIGHT BY cnCharles, ALL RIGHTS RESERVED.
delphi群: 16497064, blog: http://hi.baidu.com/cnCharles  

     //描述: cxGrid的 TableView 数据排序与对应的数据集同步, 该方法主要用于打印时
       //         的排序与所见到的排序保持一致;
       //参数: @tv: 排序的cxGridTableView
       //说明: @tv: 对应的数据集只支持 ADOQuery与 ClientDataSet;
       procedure cxGridSortSyncToDataSet(tv: TcxGridDBTableView); overload;

       //描述: 功能同上, 实现代码一样, 如果有更改就同步更改
       procedure cxGridSortSyncToDataSet(tv: TcxGridDBBandedTableView); overload;

procedure cxGridSortSyncToDataSet(tv: TcxGridDBTableView);
const
     SortArray: array[soAscending..soDescending] of string = (’ASC’, ’DESC’);
var
     AscFields, DescFields, S, SortOrder: string;
     IndexPrint: string;
     I: integer;
     Index: integer;
     cds: TClientDataSet;
begin
     S := ’’;
     AscFields := ’’;
     DescFields := ’’;
     if tv.SortedItemCount = 0 then
       Exit;
     if tv.DataController.DataSource.DataSet is TADOQuery then begin
       for I := 0 to tv.SortedItemCount - 1 do begin
         SortOrder := SortArray[tv.SortedItems[I].SortOrder];
         if S <> ’’ then
           S := S + ’, ’;
         Index := tv.SortedItems[I].Index;
         S := S + tv.Columns[Index].DataBinding.Field.FieldName + ’ ’ + SortOrder;
       end;
       (tv.DataController.DataSource.DataSet as TADOQuery).Sort := S;
     end else if (tv.DataController.DataSource.DataSet is TClientDataSet)     then begin
       Cds := tv.DataController.DataSource.DataSet as TClientDataSet;
       for I := 0 to tv.SortedItemCount - 1 do begin
         Index := tv.SortedItems[I].Index;
         S := tv.Columns[Index].DataBinding.Field.FieldName +’;’;
         AscFields := AscFields + S;
         if tv.SortedItems[I].SortOrder = soDescending then
           DescFields := DescFields + S;
       end;
       if AscFields <> ’’ then
         Delete(AscFields, Length(AscFields), 1); //删除 ;

       if DescFields <> ’’ then
         Delete(DescFields, Length(DescFields), 1);
       IndexPrint := TimeToStr(Now());
       Cds.IndexDefs.Clear;
       IndexPrint := TimeToStr(Now());
       cds.AddIndex(IndexPrint, AscFields, [], DescFields);
       cds.IndexName := IndexPrint;
     end;
end;
****************************************************************************
60 cxGRID怎么遍历已经选择的单元格
解决:
n := cxGrid1DBTableView1.DataController.GetSelectedCount; 
     
      for   i:=0   to   n   -   1   do 
      begin 
          Index   :=   cxGrid1DBTableView1.DataController.GetSelectedRowIndex(i); 
          if   Index   <   0   then   continue; 
          AccID   := 
                          cxGrid1DBTableView1.DataController.GetRowvalue( 
                          cxGrid1DBTableView1.DataController.GetRowInfo(Index) 
                          ,0); 
          AccID   :=   dsData.DataSet.FieldByName(’AccountID’).AsString; 
   
      end;
n := cxGrid1DBTableView1.DataController.GetSelectedCount; 
      for   i:=0   to   n   -   1   do 
      begin 
          Index   :=   cxGrid1DBTableView1.DataController.GetSelectedRowIndex(i); 
          if   Index   <   0   then   continue; 
          AccID   := cxGrid1DBTableView1.DataController.GetRowvalue( 
                  cxGrid1DBTableView1.DataController.GetRowInfo(Index) 
                  ,0);//这里的0是列的索引,能指定,也可用通过GridView获取 
   
      end;
****************************************************************************
61 动态设置显示格式
解决:
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;
****************************************************************************
62 给cxGRID加序号列
解决:
procedure SetRowNumber(var ASender: TcxGridTableView;
AViewInfo: TcxCustomGridIndicatorItemViewInfo;
   var ACanvas: TcxCanvas; var ADone: boolean);

uses cxLookAndFeelPainters;

procedure SetRowNumber(var ASender: TcxGridTableView; AViewInfo: TcxCustomGridIndicatorItemViewInfo;
   var ACanvas: TcxCanvas; var ADone: boolean);
var
   AIndicatorViewInfo: TcxGridIndicatorRowItemViewInfo;
   ATextRect: TRect;
   AFont: TFont;
   AFontTextColor, AColor: TColor;
begin
   AFont := ACanvas.Font;
   AColor := clBtnFace;
   AFontTextColor := clWindowText ;
if (AViewInfo is TcxGridIndicatorHeaderItemViewInfo) then begin
   ATextRect := AViewInfo.Bounds;
   InflateRect(ATextRect, -1, -1);
   
   ASender.LookAndFeelPainter.DrawHeader(ACanvas, AViewInfo.Bounds,
     ATextRect, [], cxBordersAll, cxbsNormal, taCenter, vaCenter,
     False, False, '序号', AFont, AFontTextColor, AColor);
     ADone := True;
   end ;
if not (AViewInfo is TcxGridIndicatorRowItemViewInfo) then
     Exit;
   ATextRect := AViewInfo.ContentBounds;
   AIndicatorViewInfo := AViewInfo as TcxGridIndicatorRowItemViewInfo;
   InflateRect(ATextRect, -1, -1);
   ASender.LookAndFeelPainter.DrawHeader(ACanvas, AViewInfo.ContentBounds,
     ATextRect, [], [bBottom, bLeft, bRight], cxbsNormal, taCenter, vaCenter,
     False, False, IntToStr(AIndicatorViewInfo.GridRecord.Index + 1),
     AFont, AFontTextColor, AColor);
   ADone := True;
ASender.LookAndFeelPainter.DrawIndicatorImage(ACanvas,ATextRect, AIndicatorViewInfo.IndicatorKind);
end;

如果你不要行标志的话,你可以不改控件
直接注释掉这一行: ASender.LookAndFeelPainter.DrawIndicatorImage(ACanvas, ATextRect, AIndicatorViewInfo.IndicatorKind);
要标志的话,在DrawIndicatorImage 从这里跟进去(Ctrl+左键单击)
在 cxLookAndFeelPainters 单元中作如下修改:

class procedure TcxCustomLookAndFeelPainter.DrawIndicatorImage(ACanvas: TcxCanvas;
   const R: TRect; AKind: TcxIndicatorKind);
var
   X, Y: Integer;
begin
   if AKind = ikNone then Exit;
   with cxIndicatorImages, R do
   begin
     X := (Left + Right - Width);               //靠右
     Y := (Top + Bottom - Height) div 2;       //居中
   end;
   cxIndicatorImages.Draw(ACanvas.Canvas, X, Y, Ord(AKind) - 1);
end;

注意,我已注明靠右的那一行, 就是去掉 DIV 2 了,
还要改一个地方:
SKIN控件目录下的dxSkinLookAndFeelPainter单元,找到
TdxSkinLookAndFeelPainter.DrawIndicatorImage 函数

OffsetRect(ARect, (Left + Right - cx div 2) , (Top + Bottom - cy) div 2);
这一行,将 (Left + Right - cx div 2) 改为(Left + Right - cx) 也是去掉 div 2 就是靠右;
修改后: OffsetRect(ARect, (Left + Right - cx) , (Top + Bottom - cy) div 2);

使用
procedure TForm1.cxGrid1DBTableView1CustomDrawIndicatorCell(
   Sender: TcxGridTableView; ACanvas: TcxCanvas;
   AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean);
begin
     SetRowNumber(Sender,AviewInfo,ACanvas,ADone);
end;

另外序号列的列宽最好改为25以上!
效果图:

****************************************************************************
63 cxGrid自带过滤后数据也数据集同步
解决:
在cxGrid的View Filter事件的OnBeforeChange中写代码就可以了.
procedure TForm1.tvcxgd1DBTableView1DataControllerFilterBeforeChange( Sender: TcxDBDataFilterCriteria; ADataSet: TDataSet; const AFilterText: String); begin //这里可以增加数据集控件的filter:=false; //如:adoquery.filter:=false; //如果使用的是cxgrid的汉化版本,可以将AFilterText中的中文等于,小于 替换成 = <等 //adoquery.filter:=替换了中文的AFilterText; ShowMessage(AFilterText); end; 写了上述步骤后可以在tvcxgd1DBTableView1DataControllerFilterChanged写 adoquery.filter:=true; 这样就起到了cxgrid过滤后的数据同步到adoquery

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
cxgrid使用方法
Cxgrid获取选中行列,排序规则
CXGrid的使用技巧2
Delphi 控件 cxGrid(DevExpress控件)的使用方法
cxgrid显示序号
cxgrid对经过筛选过的数据的选择(反选)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服