Delphi TdxDBGrid 使用简介

来源:互联网 发布:钢丝野猪吊脚套锁淘宝 编辑:程序博客网 时间:2024/06/06 09:48


一、如何设定可以多列自动排序?
    
只能使用分组:如按a1,a2,a3,a4排序
    先按a1分组,再a2,再a3
    然后设置a4的排列(升/降)


二、如何设定左边几列,不能滚动?
    建立Band0,Band1
    Band0的Fixed=tfLeft
    Band1的Fixed=tfnone
    设置要锁定的字段的BandIndex=0,其它为1


三、如何访问,显示字段的对象,控制其可视与不可视?
   参看自带例程RunTimeCustomizing.dpr


四、既然不能用readonly,那我用edgoEditing属性对吗?
   要想ReadOnly=True.我用edgoRowSelected=True;


DXGRID 设计排序和统计的关键前提是先指定 DXGRID 的KEY FIELD字段 然后设置它的 edgoAnsi Sort属性 为TRUE 就可以了.随便点任意字段都可以排序,如果还需要显示合计的话。 需要将edgoLoadAllRecords  设置为 True.

整理ExpressQuantumGrid控件心得如下:
  针对TdxDBGrid仅仅设置一些属性,就可以到达很好的效果:
 前提:先设置DataSource、ADODataSet、以及TdxDBGrid的属性后,设置ADODataSet的Active=true;然后才能在TdxDBGrid中的鼠标右键->
       column-> Add all Fields; 注意:一定要设置TdxDBGrid控件的属性keyField、并设置OptionsDB中edgoLoadAllRecord=true 。

 1、显示脚注栏: 设置属性showSummeryFooter=true即可。
 2、显示某一列的汇总值(或总个数): 设置summaryFooterType,为cstSum(或cstAvg)、并设置summaryFormat,即可。
 3、设置Filter:在TdxDBGrid属性中Filter组中Active=true。
 4、设置Sort:在OptionsBehavior中设置 :edgoAutoSort=true。
 5、设置汉字提示:在column中->SummaryFormat中输入样式,如:(数量=0.00)
 6、summary样式,一共分为三种:
    (1)summary:用于行的总体说明GroupNode类型。
    (2)summaryFooter:在整个Grid的底部footer处显示。
    (3)summaryRowFooter:在每个行的底部显示信息。(行,是几条记录形成的小组)。
------------------------------------------------------------------------------
在DELPHI的标准控件中很容易的用
grid.columns.add就可以加如一个列,但在DX控件中却不支持。

  dxDBGrid1.CreateColumn(TdxDBGridMaskColumn);//TdxDBGridMaskColumn,列类型
  dxDBGrid1.Columns[4].FieldName := 'City';//4列索引,City字段名称

在keyup事件中,dbgShare.Fields[4].AsFloat:=
               dbgShare.Fields[1].AsFloat*
               dbgShare.Fields[2].AsFloat*
               dbgShare.Fields[3].AsFloat;
这样的话等输完它又变回去了,如果用Post先提交,那样的话整个输入又获得了焦点,继续输的时候又把输好的给覆盖了,总之很不爽,大家可以试试。而在其他事件中,又不是实时变化。
 
  
来自:glbboy, 时间:2002-2-1 18:27:00, ID:901471 
在DBGRID事件BeforeScroll、ColExit两个事件中都加如下代码实现了汇总。
qryShare.Edit;
qryShare.Fields[4].AsCurrency:=qryShare.Fields[1].AsCurrency*
qryShare.Fields[2].AsCurrency*qryShare.Fields[3].AsCurrency;
qryShare.Post;
但有一点不好,就是对数据库操作太多了。:)
计算字段?有这个数据类型吗?说详细点OK!最好是给具体简单一点的代码!
 

  with DXDBGRID1.CreateColumn(TdxDBGridMaskColumn) as TdxDBGridMaskColumn do
              begin
                FieldName := ClientDataSet3.Fields[Ifieldcount].FieldName;
                HeaderAlignment := taCenter;
                 Width := 90;
------------------------------------------------------------------------------ 
 SaveToIni可以保存dxDBGrid的设置
------------------------------------------------------------------------------

请教关于dxDBGrid的下述两个问题
A:怎样在DefaultFields=True正常打印
B:若预设dxDBGrid的DefaultFields=False,怎样在运行时动态加入栏位或组以及打印

注:(1)数据表(DataSource)连接TClientDataSet
    (2)使用标题筛选Filter.Active=True
    (3)加入TdxComponentPrinter并设置

若预设dxDBGrid的DefaultFields为True、edgoLoadAllRecords为True并加入KeyField值、设置上述(1)、(2)、(3)时,执行打印为空不能打印dxDbGrid内容
 
------------------------------------------------------------------------------
在使用中发现了一个问题:
有些时候,在grid中选中显示的数据(即光标定位的那一条记录)和数据源中当前的记录不匹配,而且出现这种情况随机的,应该和具体的属性设置没有关系。看看哪位兄台也遇上过类似的问题,麻烦赐教!


一、keyfield设置为唯一值字段
二、LoadAllRecords:=True 
------------------------------------------------------------------------------
我在dxDBGrid中,在dxDBGrid1DQPZH列中的ONValidate事件中,怎样取得我刚输入的值,
我用dxDBGrid1DQPZH.Field.OldValue或dxDBGrid1DQPZH.Field.NewValue,均取得没修改
以前的值。

这个事件确实有问题,我的解决办法是在dxDbGrid的OnEdited中编程,代码如下
新值: dxDBGrid1.FocusedField.NewValue
旧值: dxDBGrid1.FocusedField.OldValue 
 
 来自:caodz, 时间:2002-3-1 16:06:00, ID:952000 
在dxDBGrid1ChangeColumn事件中,写
X:=dxDBGrid1DQPZH.Field.TEXT
 
------------------------------------------------------------------------------
dxDBGrid怎样用代码动态增加列,
搞定了
 with dxDBGrid1.CreateColumn(TdxDBGridButtonColumn) as TdxDBGridButtonColumn do
  begin
    FieldName := 'NAME';
  end;
------------------------------------------------------------------------------
dxdbGrid的状态栏中的汇总结果,当添加新的记录的时候,不能刷新
怎么办?应该在那里再进行一次汇总调用?
将LoadAllRecord 设为true即可.

------------------------------------------------------------------------------
 dxDBGrid的继承关系是:
  TWinControl-->TCustomControl-->TCustomdxContainer -->TCustomdxTreeList-->TCustomdxDBTreeListControl
  -->TCustomdxDBGrid-->TdxDBGrid
------------------------------------------------------------------------------
dxDBGrid如何固定某列不左右移动?
options下的egoColumnMoving设为false
------------------------------------------------------------------------------
如何知道当前DXDBGRID的行号和列号
列号和列名
  dxDBGrid.FocusedNode.Index
  dxDBGrid.FocusedColumn

如何为坐标为(2,3)行号和列号的DXDBGRID赋值?
DXDBGRID的内容是反映其关联的数据集的数据 取数据的话可以dxDBGrid.Items[2].Values[3] 但好象不能直接通过程序给它赋值(手工可以) 要用程序赋值只能对其数据集处理
给RecNo属性等于2的数据集的第2个字段赋
如在一个循环判断中
  ADOTable1.First;
  while not ADOTable1.Eof do
  begin
    if ADOTable1.RecNo = 2 then
      ADOTable1['字段二'] := 'abc';
    ADOTable1.Next;
  end;
  
ADOTable1.RecNo :=2;{记录到第二行}
ADOTable1.Fields[2] :=?? {修改第三列}
------------------------------------------------------------------------------
dxDBGrid如何知道现在在哪一列?哪一个单元格?DBGrid有SelectedIndex,dxDBGrid是何相关属性?
    dxDBGrid1.FocusedColumn
------------------------------------------------------------------------------
dxDBGrid如何用回车键、代替Tab键来移动栏位
在form的keypress事件下添加如下代码就可以了:
if key=#13 then
if (activecontrol is tdbgrid ) then
begin
 with tdbgrid(activecontrol) do
if selectedindex<(fieldcount-1) then
selectedindex:=selectedindex+1
else
selectedindex:=0;
end;

首先设置Form的KeyPreview属性为True
然后
在form的keypress事件下添加如下代码就可以了:
if key=#13 then
if (activecontrol is tdbgrid ) then
begin
 with tdbgrid(activecontrol) do
   if selectedindex<(fieldcount-1) then
   selectedindex:=selectedindex+1
 else
 begin
   dbgrid1.DataSource.DataSet.Next ;
   selectedindex:=0;
 end;

------------------------------------------------------------------------------
DxDBGrid的GroupPanel上面的英文[Drag a column header to group by that column]怎么可以改成中文?
源码包里有 RC 文件。  打开他。翻译成中文。 然后brcc32  -r *.rc 然后把生成RES 文件放到DELPHI的LIB PATH 中路径里就可以了
------------------------------------------------------------------------------
就是在任何一个单元格是双击后就可以知道那个单元在哪一个column(列)中,以运行不同的代码。
以前用DBGRID,可以在DBGrid1CellClick中获取该信息,但在DXDBGRID中如何做呢?而且我想要
双击时,不是单击的时候根据Index就可以取得Caption啊:
dxDBGrid1.FocusedNode.Strings[dxDBGrid1.FocusedColumn]
至于会不会变你试一下就行了,用上面的这句应该没有问题的。
------------------------------------------------------------------------------
dxDBgrid多选,遍历每条选中记录,将字段Name内容改为Str的内容
    if InputQuery('刊物名称输入','请输入新的刊物名称:',Str) then
      with dxDBGrid1.DataSource.DataSet do
      begin
        for I:=0 to dxDBGrid1.SelectedCount-1 do
        begin
          GoTobookmark(pointer(dxDBGrid1.SelectedRows[i]));
//          Edit;
//          FieldByName('Name').AsString := Str;
//          Post;
        end;
      end;
到第二个循环的GoTobookmark(pointer(dxDBGrid1.SelectedRows[i]));就'List Index out of bounds(1)'。

以前得我都看了,好像没有改记录内容的。

        for I:=0 to dxDBGrid1.SelectedCount-1 do
        ->for i := dxDBGrid1.SelectedCount - 1 downto 0 do
------------------------------------------------------------------------------
在DXDBGRID中,根据某字段的值而决定该行的颜色,类似DBGRID的DRAWDATACELL事件怎么写
第一个问在dxdbgrid中oncustomdrawcell事件写
 if  ASelected then afont.Color:=clred;          //选中的栏的字体设为红色
  scheck:=ANode.Values[dxDBGrid1status.Index];  //dxdbgrid1status为某一个指定字段
  if not VarIsNull(scheck) then
    if scheck = '1' then                       //这段为指定值的判定,如果为1把这一行定义为白颜色
                            
        AColor := clWhite
     else
        acolor:=clInfoBk;
        
------------------------------------------------------------------------------
在DXDBGRID控件中,有过滤功能,很方便。但现在却出现一问题,
如果我在程序中用过滤锁定一条记录后,如果重新关闭并激活数据源,
此时用QUERY.FIELDBYNAME('AAA').ASSTRING返回的结果不是激活数据源前的记录,
必须手工用鼠标指向其它行或列时才会返回光标指向的记录。如何解决?
  

首先你跟蹤看看﹐你關閉之前是不是鎖定就是你當前所要的記錄﹖
如果是把關鍵字段保存在一個變量里﹐然后用
很笨的方法﹐就是進行Talbe.locate('Field',變量,[]);
  
var
   SavePlace: TBookmark;
   PrevValue: Variant;
begin
   with Table1 do
   begin
    { get a bookmark so that we can return to the same record }
    SavePlace := GetBookmark;  
    { move to prior record}
    FindPrior; 
    { get the value }
    PrevValue := Fields[0].Value;
    {Move back to the bookmark} 
    GotoBookmark(SavePlace);
    { Set the value }
    Fields[0].Value := PrevValue;
    { Free the bookmark }
    FreeBookmark(SavePlace);
  end;
end;

ok!:)
 
 
------------------------------------------------------------------------------
用过 dxDBGrid 的大侠看过来,拖动字段分组后,怎样将指定的组中的全部行选中 ( 积分:100, 回复:3, 阅读:42 )
分类:控件 - 使用 ( 版主:amo, cAkk )  
比如:a,90;a,91;a92;b,80;b85 分组后成了

    90
    91
    92
b
    80
    85
我想将 b 组的数据选中。
 
来自:wind_cloudy, 时间:2001-6-7 14:42:00, ID:557645 
设置dxDbgrid的OptionsBehavior属性的edgoMultiSelect为true
设置dxDbgrid的OptionsView属性的edgoRowSelect为true
按住ctrl或shift键,用鼠标选择.
 
------------------------------------------------------------------------------
如何在DXDBGRID(DEV EXPRESS中的一个控件)中在列标题上出现排序的小箭头?
  
以上是DXDBGRID的帮助中有关排序的说明,也就是有两中方法去实现你的目的:
  1. 设置OptionsBehavior.egoLoadAllRecords 和 OptionsDB.egoAutoSort属性为True 就可以,不过我试了一下,要指定KeyField属性的值才有效。
  2. 在OnColumnClick事件中加入你的排序方法,以下是它的Demo中的代码:
with TdxDBGrid(Sender) do
  begin
    OldSorted := Column.Sorted;
    if (GetAsyncKeyState(VK_SHIFT) = 0) then
      TdxDBGrid(Sender).ClearColumnsSorted;

    if OldSorted = csUp then
      Column.Sorted := csDown
    else
      Column.Sorted := csUp;

    with TQuery(DataSource.DataSet) do
    begin
      ID := FieldByName('ID').AsInteger;
      DisableControls;
      try
        Close;
        SQLOrderSt := '';
        for i := 0 to SortedColumnCount - 1 do
        begin
          if SQLOrderSt <> '' then
            SQLOrderSt := SQLOrderSt + ', ';
          SQLOrderSt := SQLOrderSt + GetFieldName(SortedColumns[i]);
          if SortedColumns[i].Sorted = csDown then
            SQLOrderSt := SQLOrderSt + ' DESC';
        end;
        if SQLOrderSt <> '' then
          SQLOrderSt := 'ORDER BY ' + SQLOrderSt;
        SQL.Strings[SQL.Count - 1] := SQLOrderSt;
        Open;
        Locate('ID', ID, []);
      finally
        EnableControls;
      end;
    end;
  end;
由此我们可看到它是用动态SQL语句重新ORDER BY记录了

举例:

procedure CreatedxGridColumn(dxGrid: TdxDBGrid);
var
  I,J,K: integer;
  C: TdxDBTreeListColumnClass;
  lFieldInfo:TFieldDictInfo;
  daqLookup:TQuery;
  D:TdxDBGridPickColumn;
  sLookField,sSQL:String;
  lSQLParser:TSQLAnalysis;

  function GetListColumnsClass(AField: TField;DataSet:TDataSet): TdxDBTreeListColumnClass;
  var
    lFieldInfo:TFieldDictInfo;
    lSQLParser:TSQLAnalysis;
  begin
    lSQLParser:=TSQLAnalysis.Create;
    lSQLParser.SQLString:=(DataSet as TQuery).SQL.Text;
    try
      if AField.FieldKind = fkLookup then
        Result := TdxDBGridLookupColumn
      else begin
        if AField.FieldKind = fkData then begin
          case AField.DataType of
            ftBoolean : Result := TdxDBGridCheckColumn;
            ftDate, ftDateTime : Result := TdxDBGridDateColumn;
            ftTime : Result := TdxDBGridTimeColumn;
            ftCurrency : Result := TdxDBGridCurrencyColumn;
            ftGraphic : Result := TdxDBGridImageColumn;
            ftBytes, ftVarBytes, ftBlob, ftMemo,
              ftFmtMemo, ftParadoxOle, ftDBaseOle, ftTypedBinary :
                Result := TdxDBGridBlobColumn;
            else
              lFieldInfo := DBDictInfo.FindFieldDictInfo(AField.FieldName,lSQLParser.Froms);
              if (lFieldInfo.LookupTable <> '') and (not AField.ReadOnly) then Result := TdxDBGridPickColumn
              else Result := TdxDBGridColumn;
          end;
        end else
          Result := TdxDBGridMaskColumn;
      end;
    finally
      lSQLParser.Free;
    end;
  end;

begin
  if dxGrid.DataSource = nil then Exit;
  if dxGrid.DataSource.DataSet.FieldCount < 1 then exit;
  if dxGrid.KeyField = '' then
    dxGrid.KeyField := dxGrid.DataSource.DataSet.Fields[0].FieldName;

  for I := 0 to dxGrid.DataSource.DataSet.FieldCount - 1 do
  begin
    if not dxGrid.DataSource.DataSet.Fields[I].Visible then Continue;
//显示MEMO字段,Modified by Xufeng
    //    if (GetListColumnsClass(dxGrid.DataSource.DataSet.Fields[I],dxGrid.DataSource.DataSet) = TdxDBGridBlobColumn) then Continue;

    C := TdxDBTreeListColumnClass(GetListColumnsClass(dxGrid.DataSource.DataSet.Fields[I],dxGrid.DataSource.DataSet));
    if C <> nil then
    begin
      with dxGrid.CreateColumn(C) do
      begin
        FieldName := dxGrid.DataSource.DataSet.Fields[I].FieldName;
   //判断是否从另一个表里取数据
        if C = TdxDBGridPickColumn then
        begin
          D := TdxDBGridPickColumn(dxGrid.ColumnByFieldName(dxGrid.DataSource.DataSet.Fields[I].FieldName));
          lSQLParser:=TSQLAnalysis.Create;
          lSQLParser.SQLString:=(dxGrid.DataSource.DataSet as TQuery).SQL.Text;
          try
            lFieldInfo := DBDictInfo.FindFieldDictInfo(dxGrid.DataSource.DataSet.Fields[i].FieldName,lSQLParser.Froms);
            if lFieldInfo.LookupTable <> '' then
            begin
              daqLookup := TQuery.Create(nil);
              try
                K := Pos(';',lFieldInfo.LookupFieldsString);
                if K=0 then sLookField := lFieldInfo.LookupFieldsString
                else sLookField := Copy(lFieldInfo.LookupFieldsString,1,K-1);
                sSQL := 'Select ' + sLookField + ' from ' + lFieldInfo.LookupTable;
                if lFieldInfo.RangeField <> '' then sSQL := sSQL + ' where ' + lFieldInfo.RangeField + '=''' + lFieldInfo.RangeValue + '''';

                daqLookup.SQL.Add(sSQL);
                daqLookup.DatabaseName := GlobalInfos.DataBaseName;
                daqLookup.Open;
                for J := 1 to daqLookup.RecordCount do begin
                  D.Items.Add(daqLookup.FieldByName(sLookField).AsString);
                  daqLookup.Next;
                end;
              finally
                daqLookup.Free;
              end;
            end;
          finally
            lSQLParser.Free;
          end;
        end;
      end;
    end;
  end;
end;

 ------------------------------------------------------------------------------
DxDBGrid中哪个属性等价于DbGrid的”ReadOnly”属性.如果没有应该怎样设置
OptionBehavior中Edgoediting 设成False
或者将Optionview中的edgorowselect 设成true