使用dxNavBar动态创建应用程序菜单

一、如何动态创建dxNavBar内容:
function TMain.GetAcitonByCaption(const aCategory,aCaption: string): Integer;
var
  i: Integer;
begin
  Result := -1;
  for i := 0 to ActionManager1.ActionCount-1 do
  begin
    if System.SysUtils.SameText(TAction(ActionManager1.Actions[i]).Category,aCategory) and
       System.SysUtils.SameText(TAction(ActionManager1.Actions[i]).Caption,aCaption)
    then
    begin
      Result := i;
      Exit;
    end;
  end;
end;

procedure TMain.FormShow(Sender: TObject);
var
  aBarItem:TdxNavBarItem;
  aBarGroup:TdxNavBargroup;
  iAction :Integer;
begin
  dxNavBar1.Items.Clear;
  dxNavBar1.Groups.Clear;
  //++++++++++++++++++++++++++++++++++++++++++++++++//
  aBarGroup:=dxNavBar1.Groups.Add;
  aBarGroup.Caption := '系统设置';
 
  aBarItem:=dxNavBar1.Items.Add;
  aBarItem.Caption:= '操作员管理';
  //aBarItem.OnClick:= button1.OnClick; //绑定事件
  iAction := GetAcitonByCaption(cds_Master.FieldByName(aBarItem.Caption).AsString,sMenu);
  aBarItem.Action := TAction(ActionManager1.Actions[iAction]);

  aBarGroup.CreateLink(aBarItem); aBarItem:=dxNavBar1.Items.Add;
  aBarItem.Caption := '权限管理';
  iAction := GetAcitonByCaption(cds_Master.FieldByName(aBarItem.Caption).AsString,sMenu);
  aBarItem.Action := TAction(ActionManager1.Actions[iAction]); aBarGroup.CreateLink(aBarItem);

  aBarItem:=dxNavBar1.Items.Add;
  aBarItem.Caption := '报表设计中心';
  iAction := GetAcitonByCaption(cds_Master.FieldByName(aBarItem.Caption).AsString,sMenu);
  aBarItem.Action := TAction(ActionManager1.Actions[iAction]);
  aBarGroup.CreateLink(aBarItem);

  aBarItem:=dxNavBar1.Items.Add;
  aBarItem.Caption:= '系统退出';
  iAction := GetAcitonByCaption(cds_Master.FieldByName(aBarItem.Caption).AsString,sMenu);
  aBarItem.Action := TAction(ActionManager1.Actions[iAction]);
  aBarGroup.CreateLink(aBarItem);

  //++++++++++++++++++++++++++++++++++++++++++++++++//
  aBarGroup := dxNavBar1.Groups.Add;
  aBarGroup.Caption := '接口管理';

  aBarItem:=dxNavBar1.Items.Add;
  aBarItem.Caption := '学生基本信息接口';
  iAction := GetAcitonByCaption(cds_Master.FieldByName(aBarItem.Caption).AsString,sMenu);
  aBarItem.Action := TAction(ActionManager1.Actions[iAction]);
  aBarGroup.CreateLink(aBarItem);

  aBarItem:=dxNavBar1.Items.Add;
  aBarItem.Caption := '学生教学任务接口';
  iAction := GetAcitonByCaption(cds_Master.FieldByName(aBarItem.Caption).AsString,sMenu);
  aBarItem.Action := TAction(ActionManager1.Actions[iAction]);
  aBarGroup.CreateLink(aBarItem);

  aBarItem:=dxNavBar1.Items.Add; aBarItem.Caption := '学生教材缴费接口';
  iAction := GetAcitonByCaption(cds_Master.FieldByName(aBarItem.Caption).AsString,sMenu);      aBarItem.Action := TAction(ActionManager1.Actions[iAction]); aBarGroup.CreateLink(aBarItem);

  aBarItem:=dxNavBar1.Items.Add;
  aBarItem.Caption := '学生教材结算接口';
  iAction := GetAcitonByCaption(cds_Master.FieldByName(aBarItem.Caption).AsString,sMenu);
  aBarItem.Action := TAction(ActionManager1.Actions[iAction]);
  aBarGroup.CreateLink(aBarItem);
  //++++++++++++++++++++++++++++++++++++++++++++++++//
  aBarGroup := dxNavBar1.Groups.Add;
  aBarGroup.Caption := '帮助';

  aBarItem:=dxNavBar1.Items.Add;
  aBarItem.Caption := '用户手册';
  iAction := GetAcitonByCaption(cds_Master.FieldByName(aBarItem.Caption).AsString,sMenu);
  aBarItem.Action := TAction(ActionManager1.Actions[iAction]);
  aBarGroup.CreateLink(aBarItem);

  aBarItem.Caption := '关于……';
  iAction := GetAcitonByCaption(cds_Master.FieldByName(aBarItem.Caption).AsString,sMenu);
  aBarItem.Action := TAction(ActionManager1.Actions[iAction]);
  aBarGroup.CreateLink(aBarItem);
end; 

二、实际生成一个左边的dxBar菜单例子:

procedure TMain.InitMenuItem(dxNavBar1:TdxNavBar);
var
  iAction: Integer;
  aTag:string;
  sMenu:string;

  dxNavBarGroup:TdxNavBarGroup;
  dxNavBarItem:TdxNavBarItem;
  dxNavBarLink:TdxNavBarItemLink;
  dxNavBarSeparator:TdxNavBarSeparator;
  cds_Master,cds_Delta:TClientDataSet;

  procedure InitdxNavBar;
  begin
    dxNavBar1.Groups.Clear;
    with dxNavBar1.DefaultStyles do
    begin
      GroupHeader.Font.Name := '微软雅黑';
      GroupHeader.Font.Style := [fsBold];
      GroupHeader.Font.Size := 9;
      GroupHeader.Font.Color := clBlack;

      Item.Font.Name := '微软雅黑';
      Item.Font.Style := [];
      Item.Font.Size := 9;
      Item.Font.Color := clBlack;

      ItemHotTracked.Font.Color := clBlue;
      ItemHotTracked.Font.Style := [fsUnderline];

      ItemPressed.Font.Color := clBlue;
      ItemPressed.Font.Style := [];
    end;
  end;
  procedure OpenMaster;
  var
    sqlstr:string;
  begin
    if gb_Czy_Level='-1' then
      sqlstr := 'select 项目名称,Id from 菜单项目表 where pId=-1 order by id'
    else
      sqlstr := 'select 项目名称,Id from view_操作员权限表 where 操作员编号='+
                quotedstr(gb_Czy_ID)+' and pid=-1 order by id';
    cds_Master.XMLData := dm.OpenData(sqlstr);
  end;
  procedure OpenDelta(const id:integer);
  var
    sqlstr:string;
  begin
    if gb_Czy_Level='-1' then
      sqlstr := 'select * from 菜单项目表 where pId='+IntToStr(id)+' and pId<>-1 order by id'
    else
      sqlstr := 'select * from view_操作员权限表 where 操作员编号='+quotedstr(gb_Czy_ID)+
                ' and 是否可用=1 and pId='+IntToStr(id)+' and pId<>-1 order by id';
    cds_Delta.XMLData := dm.OpenData(sqlstr);
  end;
begin
  cds_Master := TClientDataSet.Create(nil);
  cds_Delta := TClientDataSet.Create(nil);
  try
    InitdxNavBar;//设置一些格式,清除设计期的数据等
    OpenMaster;
    while not cds_Master.Eof do
    begin
      dxNavBarGroup := dxNavBar1.Groups.Add;
      dxNavBar1.Hint := cds_Master.FieldByName('项目名称').AsString;
      dxNavBarGroup.Caption := Copy(dxNavBar1.Hint,4,100);
      dxNavBarGroup.Visible := True;
      dxNavBarGroup.Expandable := True;
      dxNavBarGroup.Expanded := dxNavBarGroup.Index < 3;
      //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//

      OpenDelta(cds_Master.FieldByName('id').AsInteger);

      cds_Delta.First;
      aTag := cds_Delta.FieldByName('Tag').AsString;
      while not cds_Delta.Eof do
      begin
        sMenu := cds_Delta.FieldByName('项目名称').AsString;
        iAction := GetAcitonByCaption(cds_Master.FieldByName('项目名称').AsString,sMenu);

        if iAction<>-1 then
        begin

          //创建一个dxBarButton,相当于创建一个菜单项
          dxNavBarItem := dxNavBar1.Items.Add;
          dxNavBarItem.Action := TAction(ActionManger1.Actions[iAction]);

          dxNavBarGroup := TdxNavBarGroup(dxNavBar1.Groups.ItemByCaption(Copy(ActionManger1.Actions[iAction].Category,4,100)));
          dxNavBarLink := dxNavBarGroup.CreateLink(dxNavBarItem);
          dxNavBarGroup.LinksUseSmallImages := True;
          //==================加分隔线,但是不成功,不知道为何?==============//
          if (cds_Delta.FieldByName('Tag').AsString<>aTag) then
          begin
            aTag := cds_Delta.FieldByName('Tag').AsString;
            if (cds_Delta.RecNo<cds_Delta.RecordCount) then
            begin
              //dxNavBarSeparator := TdxNavBarSeparator(dxNavBar1.Items.Add);//
              //dxNavBarSeparator.Name := 'dxNavBarSeparator1';
              //dxNavBarLink := dxNavBarGroup.CreateLink(dxNavBarSeparator);
              //dxNavBarLink.DisplayName := '';//
            end;
          end;
          //==================================================================//
        end;
        cds_Delta.Next;
      end; //end while ...
      cds_Master.Next;
    end;
  finally
    cds_Delta.Free;
    cds_Master.Free;
  end;
end;

三、动态生成dxBarManager内容例子(即生成“主菜单”--MainMenu):
procedure TMain.InitMenuItem(dxBarManager1: TdxBarManager);
var
  i,iAction: Integer;
  iNo,aTag:string;
  sName,sMenu,sCategory:string;
  dxBarSubItem:TdxBarSubItem;
  dxBarButton:TdxBarButton;
  dxBarItemLink:TdxBarItemLink;
  dxBarSeparator:TdxBarSeparator; //分隔线
  cds_Master,cds_Temp:TClientDataSet;
  procedure ReleasedxBarManager;
  var
    i:Integer;
  begin
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    dxBarManager1Bar1.ItemLinks.Clear;
    for i := dxBarManager1Bar1.ItemLinks.Count-1 downto 0 do
      dxBarManager1Bar1.ItemLinks.Delete(dxBarManager1Bar1.ItemLinks.Count-1);
    for i := dxBarManager1.ItemCount-1 downto 0 do
      dxBarManager1.Items[i].Free;
    for i := dxBarManager1.GroupCount-1 downto 0 do
      dxBarManager1.Groups[i].Free;

    dxBarManager1.Categories.Clear;
    dxBarManager1.Categories.Add('default');
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  end;
  procedure OpenMaster;
  var
    sqlstr:string;
  begin
    if gb_Czy_Level='-1' then
      sqlstr := 'select 项目名称,Id from 菜单项目表 where pId=-1 order by id'
    else
      sqlstr := 'select 项目名称,Id from view_操作员权限表 where 操作员编号='+
                quotedstr(gb_Czy_ID)+' and pid=-1 order by id';
    cds_Master.XMLData := dm.OpenData(sqlstr);
  end;
  procedure OpenDelta(const id:integer);
  var
    sqlstr:string;
  begin
    if gb_Czy_Level='-1' then
      sqlstr := 'select * from 菜单项目表 where pId='+IntToStr(id)+' and pId<>-1 order by id'
    else
      sqlstr := 'select * from view_操作员权限表 where 操作员编号='+quotedstr(gb_Czy_ID)+
                ' and 是否可用=1 and pId='+IntToStr(id)+' and pId<>-1 order by id';
    cds_Temp.XMLData := dm.OpenData(sqlstr);
  end;
begin
  ReleasedxBarManager;//清理dxBarManager
  cds_Master := TClientDataSet.Create(nil);
  cds_Temp := TClientDataSet.Create(nil);
  try
    OpenMaster;
    while not cds_Master.Eof do
    begin
      OpenDelta(cds_Master.FieldByName('id').AsInteger);
      if cds_Temp.RecordCount>0 then
      begin
        sCategory := cds_Master.FieldByName('项目名称').AsString;
        iNo := Copy(sCategory,1,2);
        sName := Format('dxBarSubItem%s',[iNo]);//取出【01.系统设置】中的01数字出来];
        sCategory := Copy(sCategory,4,100);

        //创建一个dxSubItem,相当于创建一个主菜单项
        dxBarSubItem := TdxBarSubItem.Create(Self);
        dxBarSubItem.Caption := sCategory;
        dxBarSubItem.Category := 0;
        dxBarSubItem.Visible := ivAlways;//ivNever;//
        dxBarSubItem.Name := sName;

        //放置在dxBar上
        dxBarItemLink := dxBarSubItem.BarManager.Bars[0].ItemLinks.Add;
        dxBarItemLink.Item := dxBarSubItem;
      end;
      //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//

      cds_Temp.First;
      aTag := cds_Temp.FieldByName('Tag').AsString;
      while not cds_Temp.Eof do
      begin
        sMenu := cds_Temp.FieldByName('项目名称').AsString;
        iAction := GetAcitonByCaption(cds_Master.FieldByName('项目名称').AsString,sMenu);

        if iAction<>-1 then
        begin
          if (cds_Temp.FieldByName('Tag').AsString<>aTag) then
          begin
            aTag := cds_Temp.FieldByName('Tag').AsString;
            if (cds_Temp.RecNo<>1) then //and (cds_Temp.RecNo<>cds_Temp.RecordCount) then
            begin
              dxBarSeparator := TdxBarSeparator.Create(Self);
              dxBarSeparator.ShowCaption := False;
              dxBarItemLink := dxBarSubItem.ItemLinks.Add;
              dxBarItemLink.Item := dxBarSeparator;
            end;
          end;
          //创建一个dxBarButton,相当于创建一个菜单项
          dxBarButton := TdxBarButton.Create(Self);//内存资源由Self负责管理
          dxBarButton.Caption := sMenu;
          dxBarButton.Action := TAction(ActionManger1.Actions[iAction]);
          dxBarButton.Category := 0;
          dxBarButton.Tag := TAction(ActionManger1.Actions[iAction]).Tag;
          //dxBarButton.Name := TAction(ActionManger1.Actions[iAction]).Name;//Format('dxBarButton_%-2d',[ii]);

          dxBarItemLink := dxBarSubItem.ItemLinks.Add;
          dxBarItemLink.Item := dxBarButton;
        end;
        cds_Temp.Next;
      end; //end while ...
      cds_Master.Next;
    end;
  finally
    cds_Temp.Free;
    cds_Master.Free;
  end;
end;
四、在实际项目中的一个截图:



五、那么能否从dxBarManager中导入内容到dxNavBar中呢?可以:

procedure TForm1.dxBarManagerTodxNavBar;
var
  i, j: Integer;
  item: TdxBarSubItem;
  group: TdxNavBarGroup;
  bar: TdxNavBarItem;
begin
  dxNavBar1.Groups.Clear;
  for i := 0 to dxBarManager1Bar1.ItemLinks.Count - 1 do
  begin
    item := TdxBarSubItem(dxBarManager1Bar1.ItemLinks[i].Control.Item);   
    group := dxNavBar1.Groups.Add;
    group.Caption := item.Caption;
    for j := 0 to item.ItemLinks.Count - 1 do
    begin
      bar := dxNavBar1.Items.Add;
      bar.Caption := item.ItemLinks.Items[j].Caption;
      bar.OnClick := dxNavBarItemClick;
      bar.SmallImageIndex := 0;
      group.CreateLink(bar);
    end;
  end;
end;

原文地址:https://www.cnblogs.com/xieyunc/p/9126538.html