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
Solved! Go to Solution.
Solved by antonio.leonardo. Go to Solution.
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
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() 🙄
@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.