AutoCAD Palette APIs
Use this skill when creating custom dockable palettes, choosing between PaletteSet/Tool Palettes/Properties Palette, or handling palette lifecycle with zero-document state.
PaletteSet and Palette
Autodesk.AutoCAD.Windows.PaletteSet is the managed wrapper over AduiPaletteSet. It inherits from Autodesk.AutoCAD.Windows.Window, implements ICollection, and hosts one or more child Palette tabs.
Autodesk.AutoCAD.Windows.Palette is a sealed class wrapping CAdUiPalette. Access its parent via Palette.PaletteSet.
Constructors
Official constructors:
PaletteSet(string name)-- creates an unnamed palette set (no persistence)PaletteSet(string name, Guid toolID)-- GUID enables automatic state persistence across sessions
Community-reported constructor (not officially documented):
PaletteSet(string name, string cmd, Guid toolID)--cmdis the command name AutoCAD replays when restoring an open palette on startup. See Gotchas for safety requirements.
Hosting Methods
Palette Add(string name, Control control)-- host a WinFormsUserControlPalette Add(string name, Uri htmlPage)-- host HTML-backed contentPalette AddVisual(string name, Visual control)-- host a WPF visual directly (no ElementHost needed)Palette AddVisual(string name, Visual control, bool bResizeContentToPaletteSize)-- WPF visual with explicit resize control. Whentrue, the WPF content resizes with the palette. Whenfalse, the content retains its natural size.
AddVisual is the preferred approach for WPF content in modern plugins. It avoids the WinForms UserControl + ElementHost wrapper that Add(string, Control) requires.
Example: WinForms Palette Singleton
using System;
using System.Drawing;
using System.Windows.Forms;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
public sealed class SamplePaletteCommands
{
private static readonly Guid PaletteId =
new Guid("E4E1D31A-8B4A-4F47-B10A-3B9E3D5C9E90");
private static PaletteSet _paletteSet;
[CommandMethod("SHOW_SAMPLE_PALETTE")]
public static void ShowSamplePalette()
{
if (_paletteSet == null)
{
_paletteSet = new PaletteSet("Sample Palette", PaletteId)
{
MinimumSize = new Size(320, 220),
KeepFocus = false
};
_paletteSet.Add("General", new SamplePaletteControl());
}
_paletteSet.Visible = true;
}
}
public sealed class SamplePaletteControl : UserControl
{
public SamplePaletteControl()
{
Dock = DockStyle.Fill;
Controls.Add(new Label
{
Dock = DockStyle.Fill,
Text = "Palette content goes here.",
TextAlign = ContentAlignment.MiddleCenter
});
}
}
Example: WPF Palette via AddVisual
using System;
using System.Drawing;
using System.Windows.Controls;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
public sealed class WpfPaletteCommands
{
private static readonly Guid PaletteId =
new Guid("6AB6F5C2-DBCB-48AC-8A55-4620D2D8CBE7");
private static PaletteSet _paletteSet;
[CommandMethod("SHOW_WPF_PALETTE")]
public static void ShowWpfPalette()
{
if (_paletteSet == null)
{
_paletteSet = new PaletteSet("WPF Palette", PaletteId)
{
MinimumSize = new Size(360, 240)
};
var view = new UserControl
{
Content = new TextBlock
{
Text = "WPF content hosted by PaletteSet.AddVisual",
Margin = new System.Windows.Thickness(16)
}
};
_paletteSet.AddVisual("Preview", view, true);
}
_paletteSet.Visible = true;
}
}
Lifecycle and Startup
Application Initialization
Implement IExtensionApplication for initialization and termination. Use assembly-level ExtensionApplication and CommandClass attributes as load-time optimization hints.
Command Context
- Without
CommandFlags.Session-- command runs in document context (tied to current drawing) - With
CommandFlags.Session-- command runs in application context (survives MDI document switches)
Palette commands often need CommandFlags.Session because they must survive document switches, remain safe with no drawing active, and interact with UI state broader than a single drawing.
Application and DocumentCollection Events
Events relevant to palette hosts:
Applicationevents --BeginQuit,QuitWillStart,Idle,EnterModal,LeaveModal. Handlers stay active until AutoCAD shuts down or you unregister them.DocumentCollectionevents --DocumentActivated,DocumentCreated,DocumentDestroyed,DocumentToBeDestroyed,DocumentBecameCurrent. Use these instead of trying to infer lifecycle from command strings likeOPEN,NEW,CLOSE,QUIT.
Zero-Document State
When no documents are open, AutoCAD exposes only a reduced application surface. Key facts:
DocumentDestroyedis the recommended event for detecting entry into zero-document state- At the time of the last document closing,
DocumentManager.Countis still1during theDocumentDestroyedcallback MdiActiveDocumentmay benull-- guard all document-dependent code paths
Autoloader
PackageContents.xml flags LoadOnCommandInvocation and LoadOnAutoCADStartup control when your module loads. For command-driven palettes, prefer LoadOnCommandInvocation for startup-performance reasons.
Recommended Pattern
- Implement
IExtensionApplication - Register application and document-collection events once in
Initialize() - Unregister them in
Terminate() - Keep the
PaletteSetas a singleton - Create the palette lazily on the first command invocation
- Use
CommandFlags.Sessionwhen the command must be safe in application context - Guard every document-dependent code path for zero-document state
Example: Lifecycle Wiring
using System;
using System.Drawing;
using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
using AcApp = Autodesk.AutoCAD.ApplicationServices.Core.Application;
[assembly: ExtensionApplication(typeof(PaletteLifecycleModule))]
[assembly: CommandClass(typeof(PaletteLifecycleModule))]
public sealed class PaletteLifecycleModule : IExtensionApplication
{
private static readonly Guid PaletteId =
new Guid("BB4DEB65-6F0A-4104-B8E9-A69A0B621B3E");
private static PaletteSet _paletteSet;
public void Initialize()
{
AcApp.QuitWillStart += OnQuitWillStart;
AcApp.DocumentManager.DocumentActivated += OnDocumentActivated;
AcApp.DocumentManager.DocumentDestroyed += OnDocumentDestroyed;
}
public void Terminate()
{
AcApp.QuitWillStart -= OnQuitWillStart;
AcApp.DocumentManager.DocumentActivated -= OnDocumentActivated;
AcApp.DocumentManager.DocumentDestroyed -= OnDocumentDestroyed;
}
[CommandMethod("SHOW_LIFECYCLE_PALETTE", CommandFlags.Session)]
public static void ShowPalette()
{
EnsurePalette();
_paletteSet.Visible = true;
}
private static void EnsurePalette()
{
if (_paletteSet != null) return;
_paletteSet = new PaletteSet("Lifecycle Palette", PaletteId)
{
MinimumSize = new Size(300, 200)
};
_paletteSet.Add("Main", new UserControl { Dock = DockStyle.Fill });
_paletteSet.Load += (sender, e) =>
{
// e.ConfigurationSection gives access to XML-backed persistence data
};
_paletteSet.StateChanged += (sender, e) =>
{
var activeDoc = AcApp.DocumentManager.MdiActiveDocument;
if (activeDoc != null)
{
activeDoc.Editor.WriteMessage(
$"\nPalette state changed: {e.NewState}");
}
};
}
private static void OnDocumentActivated(object sender,
DocumentCollectionEventArgs e)
{
// Refresh document-bound palette content here
}
private static void OnDocumentDestroyed(object sender,
DocumentDestroyedEventArgs e)
{
bool enteringZeroDocState = AcApp.DocumentManager.Count == 1;
if (enteringZeroDocState)
{
// Avoid document-dependent palette work until a new drawing exists
}
}
private static void OnQuitWillStart(object sender, EventArgs e)
{
// Unhook external resources or stop background work
}
}
Tool Palette API
The Tool Palette API lives in the Autodesk.AutoCAD.Windows.ToolPalette namespace (AcMgd.dll, AcTcMgd.dll). It is the managed wrapper layer over AcTc* ObjectARX classes -- not the same as PaletteSet.
Runtime Model
Tool palettes are catalog-backed. Your application creates catalog, palette, and tool content once; AutoCAD saves it to ATC files with a path to your module. The Tool Palette framework loads your application when the Tool Palettes window initializes. This is fundamentally different from PaletteSet:
PaletteSet-- direct custom UI host you fully control- Tool Palette API -- persistent catalog-and-tool framework managed by AutoCAD
When to Use
Use the Tool Palette API when extending the Tool Palettes window with catalog-backed tools, stock-tool behavior, or tool groups. Use PaletteSet for custom dockable UI with buttons, lists, grids, previews, and plugin-specific workflows.
For deeper Tool Palette behavior, Autodesk extension points become COM/ObjectARX oriented. The managed namespace exposes wrappers and interfaces (IAcadTool, IAcadToolContextMenu, IAcadToolDragSource, IAcadToolDropTarget), but the programming model is closer to framework customization than general-purpose dockable UI.
Example: ToolPaletteManager Command
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows.ToolPalette;
using AcApp = Autodesk.AutoCAD.ApplicationServices.Core.Application;
public sealed class ToolPaletteCommands
{
[CommandMethod("TOOLPALETTE_INFO", CommandFlags.Session)]
public static void ToolPaletteInfo()
{
ToolPaletteManager manager = ToolPaletteManager.Manager;
var editor = AcApp.DocumentManager.MdiActiveDocument?.Editor;
if (editor == null) return;
editor.WriteMessage($"\nCatalog path(s): {manager.CatalogPath}");
manager.LoadCatalogs(
CatalogTypeFlags.Catalog | CatalogTypeFlags.StockToolCatalog,
LoadFlags.LoadLinks | LoadFlags.LoadImages);
editor.WriteMessage("\nTool palette catalogs loaded.");
}
}
Properties Palette API
The Properties Palette (Property Inspector) is a COM-based module for inspecting and editing object properties. It is used by the Properties palette, Tool Palettes, Visualization Styles, and other UI hosts.
Capabilities
- Display custom properties for custom objects
- Customize property categorization and editing
- Customize the Properties palette UI
- Display properties for a custom command
- Add custom tabs to the Properties palette
When to Use
Use the Properties Palette API when your custom entities, custom objects, or commands need to participate in the built-in Properties palette. Use PaletteSet when you need a dockable window for your own commands and workflow.
Decision Matrix
| Need | Best Fit | Why |
|---|---|---|
| Dockable plugin UI with tabs, forms, WPF views, previews, command buttons | PaletteSet |
Official managed host for custom palette windows |
| Host WinForms controls in a palette | PaletteSet.Add(string, Control) |
Direct WinForms support |
| Host WPF content in a palette | PaletteSet.AddVisual(...) |
Direct WPF visual hosting (no ElementHost) |
| Host HTML content in a palette | PaletteSet.Add(string, Uri) |
Official HTML-backed overload |
| Tool catalogs, stock tools, tool groups | Tool Palette API | Framework behind the Tool Palettes feature and ATC-backed catalog model |
| Custom entity/command properties in Properties palette | Properties Palette / Property Inspector APIs | Designed specifically for property inspection and editing |
| Civil 3D-specific custom business UI | Usually PaletteSet |
Civil 3D does not have a separate managed custom-palette framework; the host API is AutoCAD |
Gotchas
Stable GUID controls state restoration -- giving a
PaletteSeta stableGuidis what lets AutoCAD restore persisted window state (docking, size, location) across sessions. Without a GUID (or with a changing one), the palette loses its position every restart. (Community-reported, strong field guidance.)3-arg constructor startup safety -- the community-reported
PaletteSet(string name, string cmd, Guid toolID)replayscmdwhen restoring an open palette on startup. The command must be idempotent, safe in application context, and safe in zero-document or temporary-document startup conditions. (Community-reported.)Restart-docked edge cases -- palettes may show hidden tabs, missing controls, or misbehaving layout only when reopening docked from persisted state. Always test: show palette -> dock -> close AutoCAD -> reopen -> verify visibility, docking, focus, and control interactivity. (Community-reported.)
Zero-document guard -- palette code that assumes
MdiActiveDocumentor a fully available command line must be guarded. DuringDocumentDestroyed,DocumentManager.Countis still1when the last document closes.KeepFocusfor interactive controls -- setKeepFocus = truewhen the palette contains text boxes, combo boxes, or other interactive controls. Without it, focus returns to the drawing editor immediately after clicking inside the palette.MdiActiveDocumentnull during construction -- the document context is not established until the palette is shown. Defer document access to event handlers orLoad, not the constructor.AddVisualresize parameter -- whenbResizeContentToPaletteSizeistrue, the WPF content stretches with the palette. Whenfalse, the content keeps its natural size. Default behavior (no bool overload) resizes content to match the palette.Load/Saveevents are XML-backed -- these fire when AutoCAD persists or restores palette state. UsePalettePersistEventArgs.ConfigurationSectionto read/write custom settings alongside the built-in state.Themed icons supersede older icon methods -- use
SetThemedIcon(...)or theLightThemedIcon/DarkThemedIconproperties for proper light/dark theme support. Older icon properties do not participate in theme switching.
Related Skills
acad-palettes-ribbon-- practical ribbon API (tabs, panels, buttons, combos) and basic PaletteSet patterns with ElementHost WPF hostingacad-events-overrules-- application/document events for palette lifecycle managementacad-editor-input-- command execution viaSendStringToExecutetriggered by palette controls