Thanks for this. So I spent the last couple days getting this going. Got a custom ribbon created using .NET, got it to load automatically using the registry and got command buttons to work properly. But the whole reason for going away from VBA and to the API was to use a Combobox populated from an external database to run various text/dimension edit commands (plus other things I had ideas for).
I got a ComboBox created, can manually populate it with buttons (I think that's how it supposed to work) but for the life of me cannot figure out how to run a command based on a button selection from a ComboBox. The problem is I cannot find any good documentation, or examples of this. the closest I've found it this:
https://forums.autodesk.com/t5/net/create-custom-ribbon-tab-and-buttons-for-autocad-mechanical-2011/...
Have my code setup exactly like this, but nothing happens. Just not sure if it's even correct.
Thinking about this further, I realize I could really hard code my commands into a split button, and forget about the ComboBox linked to the database. But then, why not just use VBA and some custom buttons using CUI?
Plus for the life of me, I cannot figure out how to add a built-in AutoCad icon into my program. I was hoping I could just:
button.LargeImage = Images.getBitmap("RCDATA_32_PRINT");
So, all in all, kind of discouraged. If anyone could point me to some good resources to ComboBox usage, I may continue on, otherwise heading back to VBA with my head down. ;(
And FYI - my latest code with the ComboBox setup like the example above that does not do anything:
//non working combobox stuff before switched in split buttons
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Media.Imaging;
using System.Reflection;
using Autodesk.AutoCAD.ApplicationServices;
using acadApp = Autodesk.AutoCAD.ApplicationServices.Application;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Ribbon;
using Autodesk.Windows;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.LayerManager;
using Autodesk.AutoCAD.Internal;
[assembly: ExtensionApplication(typeof(MyExtension.MyApplication))]
namespace MyExtension
{
// IExtensionApplication showing example
// usage of the RibbonHelper class:
public class MyApplication : IExtensionApplication
{
public void Initialize()
{
try
{
/// When the ribbon is available, do
/// initialization for it:
RibbonHelper.OnRibbonFound(this.SetupRibbon);
/// TODO: Initialize your app
}
catch (System.Exception ex)
{
Document dwg = acadApp.DocumentManager.MdiActiveDocument;
if (dwg != null)
dwg.Editor.WriteMessage(ex.ToString());
}
}
public void Terminate()
{
}
/// A method that performs one-time setup
/// of Ribbon components:
void SetupRibbon(RibbonControl ribbon)
{
/// TODO: Place ribbon initialization code here
PrecisionRibbon.Ribbon r1 = new PrecisionRibbon.Ribbon();
r1.PCTRibbon();
/// Example only: Verify our method was called
acadApp.ShowAlertDialog("SetupRibbon() called");
}
}
}
/// RibbonHelper class
namespace Autodesk.AutoCAD.Ribbon
{
public class RibbonHelper
{
Action<RibbonControl> action = null;
bool idleHandled = false;
bool created = false;
RibbonHelper(Action<RibbonControl> action)
{
if (action == null)
throw new ArgumentNullException("initializer");
this.action = action;
SetIdle(true);
}
/// <summary>
///
/// Pass a delegate that takes the RibbonControl
/// as its only argument, and it will be invoked
/// when the RibbonControl is available.
///
/// If the RibbonControl exists when the constructor
/// is called, the delegate will be invoked on the
/// next idle event. Otherwise, the delegate will be
/// invoked on the next idle event following the
/// creation of the RibbonControl.
///
/// </summary>
public static void OnRibbonFound(Action<RibbonControl> action)
{
new RibbonHelper(action);
}
void SetIdle(bool value)
{
if (value ^ idleHandled)
{
if (value)
acadApp.Idle += idle;
else
acadApp.Idle -= idle;
idleHandled = value;
}
}
void idle(object sender, EventArgs e)
{
SetIdle(false);
if (action != null)
{
var ps = RibbonServices.RibbonPaletteSet;
if (ps != null)
{
var ribbon = ps.RibbonControl;
if (ribbon != null)
{
action(ribbon);
action = null;
}
}
else if (!created)
{
created = true;
RibbonServices.RibbonPaletteSetCreated +=
ribbonPaletteSetCreated;
}
}
}
void ribbonPaletteSetCreated(object sender, EventArgs e)
{
RibbonServices.RibbonPaletteSetCreated
-= ribbonPaletteSetCreated;
SetIdle(true);
}
}
}
namespace PrecisionRibbon
{
public class Ribbon
{
////////////////////////
// define public combobox frame
public RibbonCombo cmbDimAdders = new RibbonCombo();
public Ribbon()
{
cmbDimAdders.CurrentChanged += new EventHandler<RibbonPropertyChangedEventArgs>(cmbDimAdders_CurrentChanged);
}
private void cmbDimAdders_CurrentChanged(object sender, RibbonPropertyChangedEventArgs e)
{
RibbonButton but = cmbDimAdders.Current as RibbonButton;
acadApp.ShowAlertDialog(but.Text);
}
//individual combobox function 'buttons'
[CommandMethod("MyRibbonTestCombo")]
public void RibbonComboButtontest()
{
RibbonButton btnDimAdders = new RibbonButton();
btnDimAdders.Text = "test";
btnDimAdders.ShowText = true;
btnDimAdders.CommandHandler = new MyCmdHandler();
btnDimAdders.CommandParameter = "_plot ";
//add 'buttons' to combobox
cmbDimAdders.Items.Add(btnDimAdders);
cmbDimAdders.Current = btnDimAdders;
}
[CommandMethod("PCTRibbon")]
public void PCTRibbon()
{
//////////////////////////////////////////////////
// create the buttons listed in the split button
Autodesk.Windows.RibbonButton btnPartData = new RibbonButton();
btnPartData.Text = "View Part Data";
btnPartData.ShowText = true;
btnPartData.CommandHandler = new MyCmdHandler();
btnPartData.CommandParameter = "-vbarun pct_acad.dvb!Module1.subOpenPartDataSheet ";
Autodesk.Windows.RibbonButton btnTitleRefresh = new RibbonButton();
btnTitleRefresh.Text = "Title Refresh";
btnTitleRefresh.ShowText = true;
btnTitleRefresh.CommandHandler = new MyCmdHandler();
btnTitleRefresh.CommandParameter = "-vbarun pct_acad.dvb!Module1.subUpdateEngTitleBlock ";
Autodesk.Windows.RibbonButton btnStdUpdate = new RibbonButton();
btnStdUpdate.Text = "Standards Update";
btnStdUpdate.ShowText = true;
btnStdUpdate.CommandHandler = new MyCmdHandler();
btnStdUpdate.CommandParameter = "-vbarun pct_acad.dvb!Module1.subStyleUpdate ";
////////////////////////
// create split button
RibbonSplitButton btnSplitData = new RibbonSplitButton();
// Required to avoid upsetting AutoCAD when using cmd locator
btnSplitData.Text = "Data";
btnSplitData.ShowText = true;
btnSplitData.ShowImage = true;
//btnSplitData.LargeImage = Images.getBitmap(Properties.Resources.large);
//btnSplitData.Image = Images.getBitmap(Properties.Resources.Small);
btnSplitData.Items.Add(btnPartData);
btnSplitData.Items.Add(btnTitleRefresh);
btnSplitData.Items.Add(btnStdUpdate);
//////////////////////////////////////////////////
// create the buttons listed in the split button
Autodesk.Windows.RibbonButton btnPrintCurr = new RibbonButton();
btnPrintCurr.Text = "Current Layout";
btnPrintCurr.ShowText = true;
btnPrintCurr.CommandHandler = new MyCmdHandler();
btnPrintCurr.CommandParameter = "-vbarun pct_acad.dvb!Module1.subPrintCurrentToDefault ";
Autodesk.Windows.RibbonButton btnPrintAll = new RibbonButton();
btnPrintAll.Text = "All Layouts";
btnPrintAll.ShowText = true;
btnPrintAll.CommandHandler = new MyCmdHandler();
btnPrintAll.CommandParameter = "-vbarun pct_acad.dvb!Module1.subPrintToDefault ";
Autodesk.Windows.RibbonButton btnPrintCustom = new RibbonButton();
btnPrintCustom.Text = "Custom Plot";
btnPrintCustom.ShowText = true;
btnPrintCustom.CommandHandler = new MyCmdHandler();
btnPrintCustom.CommandParameter = "_plot ";
Autodesk.Windows.RibbonButton btnPageSetup = new RibbonButton();
btnPageSetup.Text = "Page Setup";
btnPageSetup.ShowText = true;
btnPageSetup.CommandHandler = new MyCmdHandler();
btnPageSetup.CommandParameter = "_pagesetup ";
////////////////////////
// create split button
RibbonSplitButton btnSplitPrint = new RibbonSplitButton();
// Required to avoid upsetting AutoCAD when using cmd locator
btnSplitPrint.Text = "Print";
btnSplitPrint.ShowText = true;
btnSplitPrint.ShowImage = true;
//btnSplitPrint.LargeImage = Images.getBitmap(Properties.Resources.large);
//btnSplitPrint.Image = Images.getBitmap(Properties.Resources.Small);
btnSplitPrint.Items.Add(btnPrintCurr);
btnSplitPrint.Items.Add(btnPrintAll);
btnSplitPrint.Items.Add(btnPrintCustom);
btnSplitPrint.Items.Add(btnPageSetup);
////////////////////////
// configure combobox frame
cmbDimAdders.Text = "Dim Notes";
cmbDimAdders.ShowText = true;
cmbDimAdders.MinWidth = 250;
// Create a Row to add the RibbonButton
RibbonRowPanel subPanel1 = new RibbonRowPanel();
subPanel1.Items.Add(btnSplitPrint);
RibbonRowPanel subPanel2 = new RibbonRowPanel();
subPanel2.Items.Add(btnSplitData);
// Create a Ribbon panel source in which to
// place ribbon items
RibbonPanelSource panelSource =
new RibbonPanelSource();
panelSource.Title = "PCT Functions";
panelSource.Items.Add(subPanel1);
panelSource.Items.Add(new RibbonSeparator());
panelSource.Items.Add(subPanel2);
panelSource.Items.Add(new RibbonRowBreak());
panelSource.Items.Add(cmbDimAdders);
// Create a panel for holding the panel
// source content
RibbonPanel panel = new RibbonPanel();
panel.Source = panelSource;
// Create a tab to manage the above panel
RibbonTab tab = new RibbonTab();
tab.Title = "Custom Tab";
tab.Id = "CustomTab";
tab.IsContextualTab = false;
tab.Panels.Add(panel);
// Now add the tab to AutoCAD Ribbon bar...
RibbonControl ribbonControl =
Autodesk.AutoCAD.Ribbon.RibbonServices.
RibbonPaletteSet.RibbonControl;
ribbonControl.Tabs.Add(tab);
// ... and activate the tab
ribbonControl.ActiveTab = tab;
}
public class MyCmdHandler : System.Windows.Input.ICommand
{
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
Document dwg = acadApp.DocumentManager.MdiActiveDocument;
if (parameter is RibbonButton)
{
RibbonButton button = parameter as RibbonButton;
RibbonCommandItem cmd = parameter as RibbonCommandItem;
dwg.SendStringToExecute((string)cmd.CommandParameter, true, false, true);
dwg.Editor.WriteMessage("\nRibbonButton Executed: " + button.Text + "\n");
}
}
}
}
}