.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Create a custom tab in menu with Cui c#

5 REPLIES 5
SOLVED
Reply
Message 1 of 6
Anonymous
3789 Views, 5 Replies

Create a custom tab in menu with Cui c#

Hello, i have created a dll with several different commands to use in Autocad Mechanical 2018, now i would like, instead of have to write every time the command, have a custom tab in the menu where i can use buttons to call the functions i have implemented.

I have already read the documentation about CUI with c#, and followed several tutorials but i can't make appear anything.

 

This is the code i use:

[CommandMethod("CreateRibbonTabAndPanel")]
        public static void CreateRibbonTabAndPanel_Method()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            try
            {
                CustomizationSection cs = new CustomizationSection((string)Application.GetSystemVariable("MENUNAME"));
                string curWorkspace = (string)Application.GetSystemVariable("WSCURRENT");

                CreateRibbonTabAndPanel(cs, curWorkspace, "ANAW", "AcadNetAddinWizard");
                cs.Save();
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage(Environment.NewLine + ex.Message);
            }
        }

        public static void CreateRibbonTabAndPanel(CustomizationSection cs, string toWorkspace, string tabName, string panelName)
        {
            RibbonRoot root = cs.MenuGroup.RibbonRoot;
            RibbonPanelSourceCollection panels = root.RibbonPanelSources;

            //Create the ribbon panel source and add it to the ribbon panel source collection
            RibbonPanelSource panelsrc=new RibbonPanelSource(root);
            panelSrc.Text = panelSrc.Name = panelName;
            panelSrc.ElementID = panelSrc.Id = panelName + "_PanelSourceID";
            panels.Add(panelSrc);

            //Create the ribbon tab source and add it to the ribbon tab source collection
            RibbonTabSource tabsrc=new RibbonTabSource(root);
            tabSrc.Name = tabSrc.Text = tabName;
            tabSrc.ElementID = tabSrc.Id = tabName + "_TabSourceID";
            root.RibbonTabSources.Add(tabSrc);

            //Create the ribbon panel source reference and add it to the ribbon panel source reference collection
            RibbonPanelSourceReference ribPanelSourceRef = new RibbonPanelSourceReference(tabSrc);
            ribPanelSourceRef.PanelId = panelSrc.ElementID;
            tabSrc.Items.Add(ribPanelSourceRef);

            //Create the workspace ribbon tab source reference
            WSRibbonTabSourceReference tabSrcRef = WSRibbonTabSourceReference.Create(tabSrc);

            //Get the ribbon root of the workspace
            int curWsIndex = cs.Workspaces.IndexOfWorkspaceName(toWorkspace);
            WSRibbonRoot wsRibbonRoot = cs.Workspaces[curWsIndex].WorkspaceRibbonRoot;
            var wsToolbarcollection = cs.Workspaces[curWsIndex].WorkspaceToolbars;

            //Set the owner of the ribbon tab source reference and add it to the workspace ribbon tab collection
            tabSrcRef.SetParent(wsRibbonRoot);
            wsRibbonRoot.WorkspaceTabs.Add(tabSrcRef);
        }

This code is from a tutorial, so i dont mind to change it completely.

 

Thanks in advance

5 REPLIES 5
Message 2 of 6
antonio.leonardo
in reply to: Anonymous

Hi @Anonymous,

 

Bellow have some links that you can follow to take an ideia about how to do this:

1) Generate .cuix file: Creating a partial CUI file using .NET and loading it inside AutoCAD, by Kean Walmsley;

2) Changing the AutoCAD Ribbon: Modify Ribbon, by Adan Nagy;

3) A complete tutorial: AutoCAD CUI Ribbon .NET: Create Ribbon Split Buttons into Ribbon Panel, by Spiderinnet;

 

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

These codes bellow contains an example for Custom Menu Generation defined only by objects approach, not generates ".cuix" file, you can test this approach, it's stable:

[CommandMethod("CustomMenuGeneration")]
public static void CustomMenuGeneration
{
  RibbonSubPanelSource srcSubPanel = new RibbonSubPanelSource();
  srcSubPanel.Id = "customMenuRibbonSubPanelSource";
  srcSubPanel.Tag = "customMenu RibbonSubPanelSource";
  
  foreach (CustomRibbonToggleButton btn in CustomRibbonToggleButton.GetTabPanelButtons())
  {
    srcSubPanel.Items.Add(btn);
  }
  
  RibbonRowPanel rowPanel = new RibbonRowPanel();
  rowPanel.Id = "customMenuRibbonRowPanel";
  rowPanel.Tag = "customMenu RibbonRowPanel";
  rowPanel.Size = RibbonItemSize.Large;
  rowPanel.Source = srcSubPanel;
  
  RibbonPanelSource srcPanel = new RibbonPanelSource();
  srcPanel.Id = "customMenuRibbonPanelSource";
  srcPanel.Tag = "customMenu RibbonPanelSource";
  srcPanel.Title = "Tag Operations";
  srcPanel.Items.Add(rowPanel);
  
  RibbonPanel Panel = new RibbonPanel();
  Panel.Id = "customMenuRibbonPanel";
  Panel.Source = srcPanel;
  
  RibbonTab Tab = new RibbonTab();
  Tab.Id = "customMenuRibbonTab";
  Tab.Title = "customMenu";
  Tab.Tag = "customMenu RibbonTab";
  Tab.Panels.Add(Panel);
  
  RibbonControl ribbonControl = ComponentManager.Ribbon;
  ribbonControl.Tag = "customMenu RibbonControl";
  ribbonControl.Tabs.Add(Tab);
}

The other classes to auxiliar the CustomMenuGeneration Command:

public class CustomRibbonToggleButton : RibbonToggleButton
{
  public CustomRibbonToggleButton(string btnText, string description,
      System.Windows.Media.ImageSource image, CommandHandler commandHandler)
  {
    this.Tag = btnText;
    this.Text = btnText;
    this.ShowText = true;
    this.ShowImage = true;
    this.LargeImage = image;
    this.Description = description;
    this.Size = RibbonItemSize.Large;
    this.CommandHandler = commandHandler;
    this.Id = btnText.Replace(" ", "").Replace("-", "");
    this.Orientation = System.Windows.Controls.Orientation.Vertical;
  }
  
  public static IEnumerable<CustomRibbonToggleButton> GetTabPanelButtons()
  {
    yield return new CustomRibbonToggleButton("Button 01",
      "Button 01 - Description",
      ToImageSource(Properties.Resources.BitMap01_32x32),
      new CommandHandler("COMMAND_01"));
    
    yield return new CustomRibbonToggleButton("Button 02",
      "Button 02 - Description",
      ToImageSource(Properties.Resources.BitMap02_32x32),
      new CommandHandler("COMMAND_02"));
    
    yield return new CustomRibbonToggleButton("Button 03",
      "Button 03 - Description",
      ToImageSource(Properties.Resources.BitMap03_32x32),
      new CommandHandler("COMMAND_03"));
  }
  
  public static BitmapImage ToImageSource(Bitmap bitMap)
  {
    BitmapImage bImg = new BitmapImage();
    using (MemoryStream ms = bitMap.GetStreamImage())
    {
       bImg.BeginInit();
       bImg.StreamSource = new MemoryStream(ms.ToArray());
       bImg.EndInit();
    }
    return bImg;
  }
}

public class CommandHandler : System.Windows.Input.ICommand
{
  private readonly string _commandName;
  public CommandHandler(string commandName)
  {
    this._commandName = commandName;
  }
  public event EventHandler CanExecuteChanged;
  public bool CanExecute(object parameter)
  {
    return true;
  }
  public void Execute(object parameter)
  {
    try
    {
       Application.DocumentManager.MdiActiveDocument.Editor.Command(this._commandName);
    }
    catch(Exception ex)
    {
       Application.ShowAlertDialog("Error, message: " + ex.Message);
    }
  }
}

If do you want to make the "CustomMenuGeneration" execute on start, you need to configure a PackageContents.xml file with the "CustomMenuGeneration" with StartupCommand="true" (vide this article or this solution).

 

Att,

Antonio Leonardo

exam-483-programming-in-c.png

Message 3 of 6
Scott_FergusonPVMNH
in reply to: Anonymous

awesome resource, thanks for posting this!!

Message 4 of 6

Thanks mate, awesome resource!
Message 5 of 6

I'm not sure that @antonio.leonardo tested the code he posted, because AFAIK, this will not work:

 

 

Application.DocumentManager.MdiActiveDocument.Editor.Command(this._commandName);

 

 

That's from the implementation of ICommand.Execute(), which usually runs in the application context, which Editor.Command() cannot be called from.  Also, after AutoCAD 2015, Editor.Command() must include all input needed to complete the command, or it will be cancelled.

 

Looks like a job for SendStringToExecute() 🙄

Message 6 of 6
antonio.leonardo
in reply to: Anonymous

@ActivistInvestor,
This code works because it's from a real-case, at the time it was developed for plant 3d 2019/2020

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report