2016-01-28 74 views
2

在我的系统上,主菜单是完全动态的,是从数据库中的数据建立的。TMainMenu生成菜单项动态

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

让我们假设我的菜单有以下主要项目:

文件 - 客户 - 报告 - 关于

当我报告单击菜单项必须组装项目,他们是前显示。

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

存在一种在显示之前创建这些项目的方法吗?

+0

可能您将不得不将您的TMainMenu替换为其他实现。像TActionMainMenuBar或SpTBXLib中的菜单一样。 – Torbins

回答

6

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

喜欢的东西:

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; 
+0

除了隐藏物品之外,您还可以将此逻辑添加更高一级,所以点击*客户*即可。但是您的解决方案更好,因为如果您需要另一个子菜单而不是报告,它不会重新生成该项目。 – GolezTrol

+0

@GolezTrol如果我理解正确报告是主菜单的项目,而不是客户。如果它是客户中的项目,那么您的逻辑也可以应用。 –

+0

啊,我没有那样解释,但是再读一遍,我认为你是对的。那么,这仍然使你的答案是一个很好的答案。 – GolezTrol

0

允许假设你有一个DS(TDataSet的)如何加载所有的数据报告。在您放下报告菜单的那一刻,您可以调用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;