The AutoCAD ribbon runtime API is pretty handy to customize the user interface. However changes made through this API are not persistent. That means there are situations where you need some extra code to make sure your Ribbon items will still be there: that’s typically the case after a workspace switch or when changes occur due to CUI or QUICKCUI commands.
Here is a suggestion on how to handle those scenario and ensure your Ribbons remain visible:
[CommandMethod("SimpleButton")]
public void SimpleButton()
{
Autodesk.AutoCAD.ApplicationServices.Application.
SystemVariableChanged +=
new Autodesk.AutoCAD.ApplicationServices.
SystemVariableChangedEventHandler(
Application_SystemVariableChanged);
Autodesk.AutoCAD.ApplicationServices.Application.
DocumentManager.MdiActiveDocument.CommandEnded +=
new CommandEventHandler(MdiActiveDocument_CommandEnded);
CreateSimpleButton();
}
void MdiActiveDocument_CommandEnded(
object sender, CommandEventArgs e)
{
if (e.GlobalCommandName == "QUICKCUI" ||
e.GlobalCommandName == "CUI")
{
Autodesk.AutoCAD.ApplicationServices.Application.Idle +=
new EventHandler(Application_Idle);
}
}
void Application_Idle(object sender, EventArgs e)
{
if (Autodesk.Windows.ComponentManager.Ribbon != null)
{
Autodesk.AutoCAD.ApplicationServices.Application.Idle -=
new EventHandler(Application_Idle);
CreateSimpleButton();
}
}
void Application_SystemVariableChanged(
object sender,
Autodesk.AutoCAD.ApplicationServices.
SystemVariableChangedEventArgs e)
{
if (e.Name == "WSCURRENT")
{
string cmdNames =
(string)Autodesk.AutoCAD.ApplicationServices.Application.
GetSystemVariable(
"CMDNAMES");
// if the QUICKCUI or CUI command is active, returns
if (cmdNames.ToUpper().IndexOf("QUICKCUI") >= 0 ||
cmdNames.ToUpper().IndexOf("CUI") >= 0)
return;
CreateSimpleButton();
}
}
public void CreateSimpleButton()
{
Autodesk.Windows.RibbonControl ribbonControl =
Autodesk.Windows.ComponentManager.Ribbon;
RibbonTab Tab = new RibbonTab();
Tab.Title = "Test Ribbon";
Tab.Id = "TESTRIBBON_TAB_ID";
ribbonControl.Tabs.Add(Tab);
Autodesk.Windows.RibbonPanelSource srcPanel =
new RibbonPanelSource();
srcPanel.Title = "Panel1";
RibbonPanel Panel = new RibbonPanel();
Panel.Source = srcPanel;
Tab.Panels.Add(Panel);
Autodesk.Windows.RibbonButton button1 = new RibbonButton();
button1.Text = "Button";
button1.Size = RibbonItemSize.Large;
button1.Image =
getBitmap(Properties.Resources.Apps, 16, 16);
button1.LargeImage =
getBitmap(Properties.Resources.Apps, 32, 32);
button1.ShowText = true;
button1.CommandParameter = "._LINE ";
button1.CommandHandler = new SimpleButtonCmdHandler();
srcPanel.Items.Add(button1);
Tab.IsActive = true;
}
//Use: getBitmap(Properties.Resources.a_large);
BitmapImage getBitmap(Bitmap bitmap, int height, int width)
{
MemoryStream stream = new MemoryStream();
bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
BitmapImage bmp = new BitmapImage();
bmp.BeginInit();
bmp.StreamSource = new MemoryStream(stream.ToArray());
bmp.DecodePixelHeight = height;
bmp.DecodePixelWidth = width;
bmp.EndInit();
return bmp;
}
public class SimpleButtonCmdHandler :
System.Windows.Input.ICommand
{
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
if (parameter is RibbonButton)
{
// builds escape sequence to cancel active commands
string esc = "";
string cmds =
(string)Autodesk.AutoCAD.ApplicationServices.Application.
GetSystemVariable("CMDNAMES");
if (cmds.Length > 0)
{
int cmdNum = cmds.Split(new char[] { '\'' }).Length;
for (int i = 0; i < cmdNum; i++)
esc += '\x03';
}
RibbonButton button = parameter as RibbonButton;
Document doc =
Autodesk.AutoCAD.ApplicationServices.Application.
DocumentManager.MdiActiveDocument;
doc.SendStringToExecute(esc + button.CommandParameter,
true, false, false);
}
}
}