如果想通过 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 对应列,又该怎么办?请高手多指教!!!
...
(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 对应列,又该怎么办?请高手多指教!!!
解决方案 »
- 请问DELPHI怎么调用QVOD快播组件(顶者都有分)
- 无聊啊。看看这有什么区别??
- delphi读取oracle数据库中的字段的类型和长度
- 象酒店系统的房态图,每个房间的房态怎么做的,用什么控件
- Delphi 调用C++的dll问题
- 求助: 在程序里怎样把一个窗口(Form)激活变成活动窗口?
- 如何得到存储过程结果集中的一条记录?用ADOStoredProc1.fields[0].asstring; 只能得到一个字段!谢谢!
- 为什么对象释放出错? 在FormDestroy中释放对象时出现 'Invalid pointer operation'的错误。
- Hotkey 怎么显示num8了呢[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
- 系统的问题
- 大家用什么报表控件进行开发
- 求助:控件在DBGrid某一标题栏中位置的固定问题---急!!!
留个名,看看高手怎么弄
DataSource1.DataSet.FieldByName('NAME').Visible := False;//可以隐藏NAME字段了
呵呵,这样就OK喽
学习了
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
完毕!