Delphi7,Dev 4.2写了一个公共的窗体,公共窗体上放置了一个 PopupMenu1,公共窗体代码如下:unit common;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,
  cxGridDBTableView, Menus, cxGrid;type
  TfrmCommon = class(TForm)
    PopupMenu1: TPopupMenu;
  private
    { Private declarations }
  public
    { Public declarations }
    procedure InitMenuItem(AcxGridDBTableView : TcxGridDBTableView);
    procedure MenuOnClick(Sender: TObject);
    procedure DBGridDisplayInf(AcxGridDBTableView : TcxGridDBTableView);
  end;var
  frmCommon: TfrmCommon;implementation{$R *.dfm}//初始化PopupMenu中的列表
procedure TfrmCommon.InitMenuItem(AcxGridDBTableView : TcxGridDBTableView);
var
  NewItem: TMenuItem;
  I : Integer;
begin
  for I := 0 to AcxGridDBTableView.ColumnCount - 1 do
  begin
    NewItem := TMenuItem.Create(nil);
    NewItem.Caption := AcxGridDBTableView.Columns[I].Caption;
    NewItem.OnClick := MenuOnClick;
    NewItem.Checked := AcxGridDBTableView.Columns[I].Visible;
    PopupMenu1.Items.Add(NewItem);
  end;
end;procedure TfrmCommon.MenuOnClick(Sender: TObject);
begin
  TMenuItem(Sender).Checked := not TMenuItem(Sender).Checked;
  DBGridDisplayInf(TcxGridDBTableView(PopupMenu1.PopupComponent));
end;procedure TfrmCommon.DBGridDisplayInf(AcxGridDBTableView : TcxGridDBTableView);
var
  I : Integer;
begin
  for I :=0 to PopupMenu1.Items.Count-1 do
  begin
    if not PopupMenu1.Items[i].Checked then
      AcxGridDBTableView.Columns[I].Visible := False
    else
      AcxGridDBTableView.Columns[I].Visible := True;
  end;
end;end.主窗体引用 common, 主窗体放置了一个 cxGrid1,cxGrid1DBTableView1 的 PopupMenu 设置成 frmCommon.PopupMenu1,主窗体代码如下:
procedure TForm1.FormShow(Sender: TObject);
begin
  frmCommon.InitMenuItem(cxGrid1DBTableView1);
end;运行后报错,右键出现列,单击某一项报错,错误在 DBGridDisplayInf 里面的 AcxGridDBTableView.Columns[I].Visible这行,哪位大大有空帮忙看下

解决方案 »

  1.   

    首先确保你的POPMENU里的排序是跟CXGRID里的一样第二应该用是DOWNTO,因为少一个可视的话, Columns[I]是会变的var 
      I : Integer; 
    begin 
      for i:= PopupMenu1.Items.Count-1 downto 0 do      // < -- downto
      begin 
        if not PopupMenu1.Items[i].Checked then 
          AcxGridDBTableView.Columns[I].Visible := False 
        else 
          AcxGridDBTableView.Columns[I].Visible := True; 
      end; 
      

  2.   

    说错,不是 - Columns[I]是会变的 应该说是下面那情况:5(aa) 6(bb) 7(cc) 执行第5个:去掉第五个 就变成 5(bb) 6(cc) 所以执行时的下一次6就成了cc 而不是所想要的bb
      

  3.   

    dinoalex,谢谢你的回复,但是你说的好像不太对:
    1、你说的 Columns[I]会变,应该是 VisibleColumns[I] 这个会变,而不是 Columns[I]
    2、按照你所说,for i:= PopupMenu1.Items.Count-1 downto 0 do      // < -- downto
    这个也不行
      

  4.   

    DBGridDisplayInf(TcxGridDBTableView(PopupMenu1.PopupComponent)); 我用断点跟了一下,PopupMenu1.PopupComponent.Name 是 ''我是将 cxGrid1DBTableView1 的PopupMenu 设置成 PopupMenu1
      

  5.   

    CXGRID自己带有这个功能,何必自己写呢
      

  6.   

    idecl(谢三哥),怎么用这个功能啊,请赐教啊
      

  7.   

    cxGridDBTableView.OptionsCustomize.ColumnFiltering 设为True
      

  8.   


    Sorry,可能搞错了,手上没有环境,这个应该是设置过滤的。你查一下cxGird的帮助或者试试,有一个属性可以直接设置
      

  9.   

      cxGrid1DBTableView1.OptionsCustomize.ColumnsQuickCustomization := True;这样的话,所有列的前面会多一个小图标,点击就可以设置列的显示与否了
      

  10.   

    感谢 idecl(谢三哥) ,这样确实可以实现