如果想通过 PopupMenu 的菜单控制 DBGrid 中各列的显示/隐藏,如 PopupMenu 的三个菜单:编号、姓名、工资(Caption属性)的 Name(控件名称) 分别为 N1、N2、N3,控制 DBGrid 中的对应列。我在 N1、N2、N3 共用的 OnClick 事件中写了一部分程序(想了点小方法,先在界面设计阶段将 N1、N2、N3 的 Tag 分别设置为 100、101、102),如下:procedure TForm1.N1Click(Sender: TObject);
...
  (Sender as TMenuItem).Checked := not (Sender as TMenuItem).Checked;
  //if Sender = N1 then DBGrid1.Columns[0].Visible := N1.Checked;
  //if Sender = N2 then DBGrid1.Columns[1].Visible := N2.Checked;
  //if Sender = N3 then DBGrid1.Columns[2].Visible := N3.Checked;
  //以下是简化的小方法
  DBGrid1.Columns[(Sender as TMenuItem).Tag - 100].Visible := (Sender as TMenuItem).Checked;
...   这在 DBGrid 的各列没有拖动(变换位置)时可行得通,但在拖动后就对应不起来了。主要是 DBGrid 的各列不是一个单独的控件,没有象 N1、N2、N3 一样有固定的控件名称来对应控制 Visible 属性。如果再增加点难度,有另两个按钮 Button1、Button2 的显示/隐藏对应与 DBGrid 中姓名、工资列的显示/隐藏完全一致,该如何操作?
   好象有一种方法,在 DBGrid 的 OnColumnMoved 事件中,按照 DBGrid 拖动后各列的位置生成对应的菜单,如 DBGrid 的列排列为:工资、编号、姓名,PopupMenu 从上到下的排序也如此(可以在 TCheckListBox 中这样实现),但不知具体如何在 PopupMenu 中实现?是不是每次要动态创建 N1、N2、N3,又要动态释放?且如果 PopupMenu 的三个菜单:编号、姓名、工资保持不变,而要显示/隐藏已经拖动后的 DBGrid 对应列,又该怎么办?请高手多指教!!!

解决方案 »

  1.   

    你不去控制DBGRID控件,控件dataset的列的显示如何?
      

  2.   

    试了下,datasource.dataset.FieldDefs中没有visible这个属性,操作不了
    留个名,看看高手怎么弄
      

  3.   

    晕,我弄错了,可以的哦,谢谢二楼的
    DataSource1.DataSet.FieldByName('NAME').Visible := False;//可以隐藏NAME字段了
    呵呵,这样就OK喽
    学习了
      

  4.   

    AdoTable1.Fields.Fields[0].Visible=False;
      

  5.   

    Delphi大富翁论坛里有高手教我了,分享给各位,具体程序如下:
    procedure TForm1.PopupMenu1Popup(Sender: TObject);
    var
      MenuItem: TMenuItem;
      iTemp: Integer;
    begin
      PopupMenu1.Items.Clear;
      for iTemp := 0 to DBGrid1.Columns.Count - 1 do
      begin
        MenuItem := TMenuItem.Create(PopupMenu1);
        with MenuItem do
        begin
          AutoCheck := True;
          //与 MenuItemClick 中的 (Sender as TMenuItem).Checked := not (Sender as TMenuItem).Checked; 功效一致,但不能同时用
           Caption := DBGrid1.Columns[iTemp].FieldName;
          Checked := DBGrid1.Columns[iTemp].Visible;
          Tag := DBGrid1.Columns[iTemp].ID + 100;
          //用 Tag 是一种小方法,其实也可用 PopupMenu1.Items.Find(ACaption) 与 Column.FieldName 来定位关联
           //或可编写一简单函数传递,如传入参数是 MenuItem 类型,返回的 Result 是 Column 类型即可
           OnClick := MenuItemClick;
        end;
        PopupMenu1.Items.Add(MenuItem);
      end;
    end;procedure TForm1.MenuItemClick(Sender: TObject);
    var
      FindCol: TColumn;
    begin         
      //(Sender as TMenuItem).Checked := not (Sender as TMenuItem).Checked;          
      FindCol := TColumn(DBGrid1.Columns.FindItemID((Sender as TMenuItem).Tag - 100));
      FindCol.Visible := (Sender as TMenuItem).Checked;
      if Copy((Sender as TMenuItem).Caption, 1, 4) = '姓名' then
      //因为 Caption 是 姓名(&X) 或 (&Y) 或 (&Z),所以要用 Copy 截取,而用 Find 不需要,是否 Find 是模糊查询?
         Button1.Visible := PopupMenu1.Items.Find('姓名).Checked;
        //或可用 Button1.Visible :=(Sender as TMenuItem).Checked;
        //如果不用 if 判断语句,则 Button1.Visible 和 Button2.Visible 的赋值语句都要执行,即会多执行一次,且上面这条语句执行会出错,只能用 Find 的那一条语句
      if Copy((Sender as TMenuItem).Caption, 1, 4) = '工资' then
        Button2.Visible := PopupMenu1.Items.Find('工资').Checked;
    end;Delphi大富翁论坛中该问题地址:http://www.delphibbs.com/delphibbs/dispq.asp?lid=3819490
    完毕!