TMainMenu构建菜单项动态

时间:2016-01-28 11:18:51

标签: delphi menu menuitem

在我的系统上,主菜单是完全动态的,是根据数据库中的数据构建的。

我有一个特定的情况,在显示之前需要组装一些菜单项。

我们假设我的菜单包含以下主要内容:

文件 - 客户 - 报告 - 关于

当我点击报告时,菜单项必须在项目显示之前组合。

我对TMainMenu,TMenu和TMenuItem类中的代码进行了分析。不幸的是,我还没有找到解决问题的简单方法。

在显示之前是否存在创建这些项目的方法?

2 个答案:

答案 0 :(得分:6)

你可以使用一个技巧。您需要在报告下添加一个虚拟TMenuItem,并将其Visible属性设置为False。然后将OnClick事件添加到报告项目,并在那里执行填充逻辑。在添加新项目之前,您必须删除现有项目,但是应该保留虚拟项目。

类似的东西:

procedure TForm1.ReportItemClick(Sender: TObject);
var
  Item: TMenuItem;
  I: Integer;
begin
  // Delete all items but first - dummy - one
  for I := ReportItem.Count - 1 downto 1 do
    ReportItem.Items[I].Free;

  Item := TMenuItem.Create(ReportItem);
  Item.Caption := 'abc';
//  Item.OnClick := ...
//  or
//  Item.Action := ...
  ReportItem.Add(Item);

  Item := TMenuItem.Create(ReportItem);
  Item.Caption := '123';
//  Item.OnClick := ...
//  or
//  Item.Action := ...
  ReportItem.Add(Item);
end;

答案 1 :(得分:0)

让我们假设您有一个DS(TDataSet)如何加载所有数据报告。在您删除Reports菜单的那一刻,您可以调用UpdateMenuReport。

type
TMenuArray = array of TMenuItem;

var MyMenu: TMenuArray;

procedure TMain.MyClickPopupMenu(Sender: TObject);
begin
    case TMenuItem(TMenuItem(Sender).Parent).Tag of
        // do Something
    end;
end;


procedure TMain.UpdateMenuReport;
    procedure InitMyMenu(var AMenu: TMenuArray);
    var i: Integer;
    begin
      if Length(AMenu)>0 then for i:= 0 to Length(AMenu)-1 do AMenu[i].Free;
      SetLength(AMenu, 0);
    end;
var j, i: integer;
begin
    InitMyMenu(MyMenu);
    Reports.Clear;
    if DS.Active and (DS.RecordCount > 0) then
    begin
        SetLength(MyMenu, DS.RecordCount);
        for i:= 0 to DS.RecordCount-1 do
        begin
            MyMenu[i] := TMenuItem.Create(Self);
            MyMenu[i].Name := 'Reports_'+ IntToStr(i);
            MyMenu[i].Caption := DS.FieldByname('NOM_REPORT').AsString;
            MyMenu[i].Tag := DS.FieldByname('ID').AsInteger;
            MyMenu[i].OnClick := MyClickPopupMenu;
        end;
    end;
end;