【问题标题】:Programatically enable a menu item (and all it's parents) - Delphi以编程方式启用菜单项(及其所有父项) - Delphi
【发布时间】:2015-01-20 14:16:29
【问题描述】:

我需要根据用户的状态有选择地启用某些菜单项。我已经设法获取代码来启用我想要的实际项目,但我看不到如何启用我在多级菜单中启用的每个父菜单项之上的所有父菜单项。如果不启用它们,菜单项仍然无法使用,因为用户无法访问它。

如果我有

EditTop
   EditSub1
   Editsub2
      EditSubSub1
   EditSub3 

我可以启用 EditSubSub1,但我还需要启用 Editsub2 和 EditTop,否则用户无法访问。这就是我希望提供的帮助。

我现在的代码如下(假设其他代码给了我一个包含我想要启用的菜单名称的 TstringList)

首先一些代码禁用一切。

procedure DisableMenu(AMenu: TMenuItem);
//recurses through all the menu and disables eveything 
var
  i: integer;
begin
for i := 0 to AMenu.Count - 1 do
   begin
   AMenu[i].enabled := false;
   DisableMenu(AMenu[i]);
   end;
end;

然后是根据名称搜索并返回 TmenuItem 的代码 (这来自 http://www.delphipages.com/forum/showthread.php?t=45723)

function FindMnuItem(Menu: TMenu; MenuName: string): TMenuItem;

      procedure FindSubItems(mnuItem: TMenuItem);
      var i: integer;
      begin
        for i:=0 to mnuItem.Count- 1 do
          if mnuItem.Items[i].Name= MenuName then
             begin
             Result:= mnuItem.Items[i];
             break;
             end
          else
             FindSubItems(mnuItem.Items[i]);
      end;

var i: integer;
begin
Result:= nil;
for i:= 0 to Menu.Items.Count -1 do
    begin
    if Menu.Items[i].name = MenuName then
       begin
       Result:= Menu.Items[i];
       break;
       end
    else
       if Result<> nil then
          break
       else
          FindSubItems(Menu.Items[i]);
    end;
end;

最后是我需要帮助的代码。这会根据 Stringlist AllowedMenus 中的名称选择性地启用每个菜单项,但仅启用这些名称,而不是树中每个菜单项上方的名称。我该怎么做?

//first disable all menu items
DisableMenu(MainMenu1.Items); 
//now enable the ones we want enabled       
for i := 0 to AllowedMenus.count-1 do
    begin
    MenuName := AllowedMenus[i];
    FindMnuItem(MainMenu1, MenuName).Enabled := true; //enable an item   
    end

【问题讨论】:

  • 您可以使用 Actions 并为每个操作编写一个 OnUpdate 事件处理程序。

标签: delphi delphi-2009


【解决方案1】:

您需要做的就是使用 TMenuItem.Parent 属性沿菜单树向上移动。

var vMenuItem : TMenuItem;
[...]
//first disable all menu items
    DisableMenu(MainMenu1.Items); 
    //now enable the ones we want enabled       
    for i := 0 to AllowedMenus.count-1 do
    begin
      MenuName := AllowedMenus[i];
      vMenuItem := FindMnuItem(MainMenu1, MenuName);
      while Assigned(vMenuItem) do
      begin
        vMenuItem.Enabled := true; //enable an item   
        vMenuItem := vMenuItem.Parent;
      end;
    end

【讨论】:

  • 谢谢,解决办法很明显了!
【解决方案2】:

我认为你可以使用这个功能; (D21 是你的实际物品):

procedure UpdateMenuParent(MyItemMenu: TMenuItem);
begin
  TMenuItem(MyItemMenu).Enabled := true;
  if TMenuItem(MyItemMenu).Parent <> nil then
    UpdateMenuParent(TMenuItem(MyItemMenu).Parent);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  UpdateMenuParent(D21);
end;

【讨论】:

  • 谢谢,我给了肯的答案,虽然他先到了那里,他的回答直接使用了我已经编写的代码。
猜你喜欢
  • 1970-01-01
  • 2012-10-26
  • 2011-10-31
  • 1970-01-01
  • 2012-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-17
相关资源
最近更新 更多