Design-Time Infrastructure
The Visual Studio design-time experience architecture for Beep Controls — smart-tags, designer verbs, property serialization, and layout manipulation at design time
Table of Contents
Overview
Every Beep control participates in the Visual Studio design-time experience through a dedicated Control Designer class. Designers control what happens when you drag a control from the Toolbox, click the smart-tag glyph, set properties, or right-click for context menu commands.
The design-time infrastructure lives in TheTechIdea.Beep.Winform.Controls.Design.Server project and is organized into five layers:
| Layer | Role | Examples |
|---|---|---|
| Base Designer Classes | Abstract designers with IComponentChangeService + CommonBeepControlActionList | BaseBeepControlDesigner, BaseBeepParentControlDesigner |
| Control Designers | Per-control smart-tag surfaces and designer verbs | BeepGridProDesigner, BeepChartDesigner |
| Action Lists | Smart-tag property grids rendered in the designer panel | BeepGridProActionList, DocumentHostActionList |
| Docking/Container | Complex layout manipulation for panels, dockspaces, MDI | DockPanelDesigner, BeepDockingManagerDesigner |
| Infrastructure | Wiring helpers, dialogs, collection editors, type converters | BeepDockingDesignerWiring, BeepGridColumnEditorDialog |
Designer Hierarchy
Beep uses Microsoft.DotNet.DesignTools as the design-time platform. The hierarchy is:
// Abstract base for all leaf controls (buttons, labels, grids, charts...)
public abstract class BaseBeepControlDesigner : ControlDesigner, IBeepDesignerActionHost
{
protected IComponentChangeService ChangeService;
protected BaseControl BeepControl;
public void SetProperty(string name, object value);
public T GetProperty<T>(string name);
public void ApplyTheme();
protected abstract DesignerActionListCollection GetControlSpecificActionLists();
}
// Abstract base for container/parent controls (panels, tabs, DocumentHost...)
public abstract class BaseBeepParentControlDesigner : ControlDesigner, IBeepDesignerActionHost
{
// Same pattern, separated for future ParentControlDesigner migration
public void SetProperty(string name, object value);
public T GetProperty<T>(string name);
public void ApplyTheme();
}Each concrete designer overrides GetControlSpecificActionLists() to add its smart-tag. The ActionLists property automatically combines control-specific lists with CommonBeepControlActionList (style/theme/schema for every control).
IBeepDesignerActionHost Interface
public interface IBeepDesignerActionHost
{
IComponent Component { get; }
void SetProperty(string propertyName, object value);
T GetProperty<T>(string propertyName);
void ApplyTheme();
}Smart-Tag (Action List) System
Smart-tags are the property panel that opens when clicking the glyph (▼) on a selected control. They use DesignerActionList subclasses.
How It Works
- The designer's
ActionListsproperty returns a collection of action lists - Each action list exposes public properties (become editable items) and void methods (become clickable links)
- The
GetSortedActionItems()override organizes items into named categories
BeepGridProActionList — 47 Smart-Tag Items
The largest single-control action list in the library, organized into 7 sections:
| Section | Properties |
|---|---|
| Quick Configuration | ConfigureAsDataDisplay(), ConfigureAsDataEntry(), ConfigureAsSimpleList(), ConfigureAsSelectionGrid(), GenerateSampleData(), EditColumns(), BestFitVisibleColumns() |
| Row Height Presets | SetStandardRowHeight(), SetCompactRowHeight(), SetComfortableRowHeight() |
| Features | EnableAllFeatures(), DisableInteractiveFeatures() |
| Data | DataSource, DataMember |
| Layout | RowHeight, ColumnHeaderHeight, ShowColumnHeaders, ShowNavigator, AutoSizeColumnsMode, AutoSizeTriggerMode |
| Appearance | GridStyle, GridTitle, NavigationStyle, ShowCheckBox, MultiSelect, ReadOnly |
| Filtering | ShowTopFilterPanel, TopFilterPanelHeight, SortIconVisibility, FilterIconVisibility |
DocumentHostActionList — 40+ Items, 18 Sections
The richest action list, covering document management, split views, tab configuration, theming, and session state.
Designer Verbs
Designer verbs appear in the right-click context menu at design time. Override the Verbs property.
BeepDockingManagerDesigner (15 verbs)
| Verb | Description |
|---|---|
| Add Panel Left/Right/Top/Bottom/Fill | Creates a new DockPanel at the specified edge |
| Move Selected Panel Left/Right/Top/Bottom/Fill | Repositions currently selected panel |
| Stack Selected with Previous/Next Panel | Groups selected panel as a tab with adjacent panel |
| &Validate Panels | Verifies all panels have valid Keys |
| Attach &Host Form | Auto-detects and assigns the parent Form |
DockPanelDesigner (10 verbs)
| Verb | Description |
|---|---|
| Dock Left/Right/Top/Bottom/Fill | Move panel to a dock edge |
| Stack with Previous/Next Panel | Group as a tab with adjacent panel |
| Move Earlier/Later in Stack | Reorder within tab group |
| &Remove Panel | Delete the panel |
IComponentChangeService & Serialization
All property mutations at design time must route through IComponentChangeService for proper .designer.cs code generation.
public void SetProperty(string propertyName, object value)
{
PropertyDescriptor property =
TypeDescriptor.GetProperties(Component)[propertyName];
ChangeService?.OnComponentChanging(Component, property); // undo
property.SetValue(Component, value); // set
ChangeService?.OnComponentChanged(Component, property, // serialize
null, value);
}This three-step pattern ensures: Undo support (OnComponentChanging), property update, code generation (OnComponentChanged). Without it, changes made in designers would not persist to the .designer.cs file.
Docking Design-Time
The docking design-time system is the most sophisticated in the library, modeled after Krypton's KryptonDockingManager:
- BeepDockingManagerDesigner — Non-visual component designer (tray component). Auto-detects host form on drop.
- DockPanelDesigner — ParentControlDesigner for individual panels. Auto-generates unique Keys. Snap-to-edge when moved.
- BeepDockspaceDesigner — ParentControlDesigner for dockspace controls. Tab drag-drop within header.
All mutations route through BeepDockingDesignerWiring, a static helper that provides Panel CRUD, Move, Stack, Resize, and host-layout-refresh operations with proper IComponentChangeService notifications.
DocumentHost Design-Time
The DocumentHost design-time experience (DevExpress parity) includes:
- BeepDocumentHostDesigner — Accepts any control via CanParent, routes drops to active document area
- DocumentHostActionList — 40+ smart-tag items across 18 organized sections
- BeepDocumentPanelDesigner — Filters Properties window to 5 meaningful properties
- Tab click → Properties window updates for selected document panel
- Smart-tag verbs: Add/Clear Documents, Apply Layout Presets, Edit Design-Time Documents, Setup Wizard
Creating Custom Designers
For a Leaf Control
[Designer(typeof(MyControlDesigner))]
public class MyControl : BaseControl
{
public string CustomProp { get; set; } = "Default";
}
public class MyControlDesigner : BaseBeepControlDesigner
{
public MyControl MyCtrl => (MyControl)Component;
protected override DesignerActionListCollection GetControlSpecificActionLists()
{
return new DesignerActionListCollection
{
new MyActionList(Component)
};
}
}
internal class MyActionList : DesignerActionList
{
private MyControlDesigner Designer =>
(MyControlDesigner)Component.Designer;
public string CustomProp
{
get => Designer.GetProperty<string>(nameof(customProp));
set => Designer.SetProperty(nameof(customProp), value);
}
public override DesignerActionItemCollection GetSortedActionItems()
{
var items = new DesignerActionItemCollection();
items.Add(new DesignerActionHeaderItem("Custom"));
items.Add(new DesignerActionPropertyItem(
nameof(CustomProp), "Custom Property", "Custom"));
return items;
}
}Class Reference
| Class | Namespace | Base Class | Usage |
|---|---|---|---|
| BaseBeepControlDesigner | Designers | ControlDesigner | Abstract base for leaf controls |
| BaseBeepParentControlDesigner | Designers | ControlDesigner | Abstract base for containers |
| BeepGridProDesigner | Designers | BaseBeepControlDesigner | 47 smart-tag items, configure presets |
| BeepChartDesigner | Designers | BaseBeepControlDesigner | Title, legend, grid smart-tag |
| BeepCalendarDesigner | Designers | BaseBeepControlDesigner | Week numbers, today button |
| BeepDockDesigner | Designers | BaseBeepControlDesigner | 14 props, 9 style presets, 4 positions |
| BeepComboBoxDesigner | Designers | BaseBeepControlDesigner | ComboBox-specific smart-tag |
| BeepMenuBarDesigner | Designers | BaseBeepControlDesigner | Menu bar design-time actions |
| BeepAccordionMenuDesigner | Designers | BaseBeepControlDesigner | Accordion menu designer |
| BeepDockingManagerDesigner | Docking.Designers | ComponentDesigner | Tray component, 15 verbs |
| DockPanelDesigner | Docking.Designers | ParentControlDesigner | 10 verbs, auto-key, snap-to-edge |
| BeepDockspaceDesigner | Docking.Designers | ParentControlDesigner | Tab drag-drop, header routing |
| DocumentHostActionList | ActionLists | DesignerActionList | 40+ items, 18 sections |
| CommonBeepControlActionList | ActionLists | DesignerActionList | Style/Theme/Schema for all |
| BeepDockingDesignerWiring | Docking.Infrastructure | Static helper | Panel CRUD, move, resize |