--- source_files: - Common/DTS.Common/RibbonControl/Classes/ButtonData.cs - Common/DTS.Common/RibbonControl/Classes/SeparatorData.cs - Common/DTS.Common/RibbonControl/Classes/GalleryItemData.cs - Common/DTS.Common/RibbonControl/Classes/ComboBoxData.cs - Common/DTS.Common/RibbonControl/Classes/MenuItemData.cs - Common/DTS.Common/RibbonControl/Classes/SplitMenuItemData.cs - Common/DTS.Common/RibbonControl/Classes/ApplicationMenuItemData.cs - Common/DTS.Common/RibbonControl/Classes/ApplicationSplitMenuItemData.cs - Common/DTS.Common/RibbonControl/Classes/TextBoxData.cs - Common/DTS.Common/RibbonControl/Classes/CheckBoxData.cs - Common/DTS.Common/RibbonControl/Classes/RadioButtonData.cs - Common/DTS.Common/RibbonControl/Classes/ToggleButtonData.cs - Common/DTS.Common/RibbonControl/Classes/SplitButtonData.cs - Common/DTS.Common/RibbonControl/Classes/ContextualTabGroupData.cs - Common/DTS.Common/RibbonControl/Classes/ViewModel.cs - Common/DTS.Common/RibbonControl/Classes/GalleryCategoryData.cs - Common/DTS.Common/RibbonControl/Classes/TabData.cs - Common/DTS.Common/RibbonControl/Classes/RibbonData.cs - Common/DTS.Common/RibbonControl/Classes/GalleryData.cs - Common/DTS.Common/RibbonControl/Classes/ControlData.cs - Common/DTS.Common/RibbonControl/Classes/MenuButtonData.cs - Common/DTS.Common/RibbonControl/Classes/GroupData.cs generated_at: "2026-04-16T03:24:01.428865+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "1a23dab67957c1ec" --- # RibbonControl Data Model Documentation ## 1. Purpose This module defines the data model layer for a ribbon UI control framework. It provides a hierarchy of data classes that represent the structure and state of ribbon UI elements—including tabs, groups, controls, menus, galleries, and context-aware groupings—enabling data binding and declarative UI construction. The classes are designed to support MVVM patterns through `INotifyPropertyChanged` implementations and command binding, with static default data generation via `ViewModelData` for design-time and testing scenarios. The module serves as the backend data contract for a WPF-based ribbon control implementation. ## 2. Public Interface ### Core Data Classes #### `ButtonData` - **Inherits from**: `ControlData` - **Description**: Represents a standard button control in the ribbon. No additional properties beyond those inherited from `ControlData`. #### `SeparatorData` - **Inherits from**: `ControlData` - **Description**: Represents a visual separator between controls. No additional properties beyond `ControlData`. #### `GalleryItemData` - **Inherits from**: `ControlData` - **Description**: Represents an individual item within a gallery. No additional properties beyond `ControlData`. #### `ComboBoxData` - **Inherits from**: `MenuButtonData` - **Description**: Represents a combo box control. Inherits all properties and behavior from `MenuButtonData`. #### `TextBoxData` - **Inherits from**: `ControlData` - **Properties**: - `string Text`: Gets/sets the text content. Raises `PropertyChanged` on change. #### `CheckBoxData` - **Inherits from**: `ControlData` - **Properties**: - `bool IsChecked`: Gets/sets the checked state. Raises `PropertyChanged` on change. #### `RadioButtonData` - **Inherits from**: `ControlData` - **Properties**: - `bool IsChecked`: Gets/sets the checked state. Raises `PropertyChanged` on change. #### `ToggleButtonData` - **Inherits from**: `ControlData` - **Properties**: - `bool IsChecked`: Gets/sets the checked state. Raises `PropertyChanged` on change. #### `SplitButtonData` - **Inherits from**: `MenuButtonData` - **Properties**: - `bool IsChecked`: Gets/sets the checked state. Raises `PropertyChanged` on change. - `bool IsCheckable`: Gets/sets whether the button can be toggled. Raises `PropertyChanged` on change. - `ButtonData DropDownButtonData`: Returns a lazily-initialized `ButtonData` instance representing the dropdown portion of the split button. #### `MenuItemData` - **Inherits from**: `SplitButtonData` - **Constructors**: - `MenuItemData()`: Calls `this(false)`. - `MenuItemData(bool isApplicationMenu)`: Calls base constructor with `isApplicationMenu`. - **Description**: Represents a menu item. Inherits all properties from `SplitButtonData`. #### `SplitMenuItemData` - **Inherits from**: `MenuItemData` - **Constructors**: - `SplitMenuItemData()`: Calls `this(false)`. - `SplitMenuItemData(bool isApplicationMenu)`: Calls base constructor with `isApplicationMenu`. - **Description**: Represents a split menu item (menu item with dropdown). Inherits all properties from `MenuItemData`. #### `ApplicationMenuItemData` - **Inherits from**: `MenuItemData` - **Constructors**: - `ApplicationMenuItemData()`: Calls `this(false)`. - `ApplicationMenuItemData(bool isApplicationMenu)`: Calls base constructor with `isApplicationMenu`. - **Description**: Represents a menu item specifically intended for use in the application menu. Inherits all properties from `MenuItemData`. #### `ApplicationSplitMenuItemData` - **Inherits from**: `SplitMenuItemData` - **Constructors**: - `ApplicationSplitMenuItemData()`: Calls `this(false)`. - `ApplicationSplitMenuItemData(bool isApplicationMenu)`: Calls base constructor with `isApplicationMenu`. - **Description**: Represents a split menu item for the application menu. Inherits all properties from `SplitMenuItemData`. #### `ControlData` - **Base class** for all ribbon control data classes. - **Properties**: - `string Label` - `Uri LargeImage` - `Uri SmallImage` - `string ToolTipTitle` - `string ToolTipDescription` - `Uri ToolTipImage` - `string ToolTipFooterTitle` - `string ToolTipFooterDescription` - `Uri ToolTipFooterImage` - `ICommand Command` - `string KeyTip` - All properties raise `PropertyChanged` on change. #### `MenuButtonData` - **Inherits from**: `ControlData` - **Constructors**: - `MenuButtonData()`: Calls `this(false)`. - `MenuButtonData(bool isApplicationMenu)`: Initializes with `isApplicationMenu` flag. - **Properties**: - `bool IsVerticallyResizable` - `bool IsHorizontallyResizable` - `ObservableCollection ControlDataCollection`: Lazily-initialized collection containing galleries, menu items, split menu items, and separators (see implementation for exact composition). - **Note**: Uses internal `_nestingDepth` field to limit recursive menu nesting. #### `GalleryCategoryData` - **Inherits from**: `ControlData` - **Properties**: - `ObservableCollection GalleryItemDataCollection`: Lazily-initialized collection of 10 `GalleryItemData` instances with default values (label, images, tooltips, command). - **Generic variant** `GalleryCategoryData` also exists with `ObservableCollection GalleryItemDataCollection`. #### `GalleryData` - **Inherits from**: `ControlData` - **Properties**: - `ObservableCollection CategoryDataCollection`: Lazily-initialized collection of 3 `GalleryCategoryData` instances with default values. - `GalleryItemData SelectedItem`: Gets/sets the selected item. Raises `PropertyChanged` on change. - `bool CanUserFilter`: Gets/sets whether filtering is enabled. Raises `PropertyChanged` on change. - **Generic variant** `GalleryData` also exists with `ObservableCollection> CategoryDataCollection` and `T SelectedItem`. #### `ContextualTabGroupData` - **Implements**: `INotifyPropertyChanged` - **Constructors**: - `ContextualTabGroupData()`: Calls `this(null)`. - `ContextualTabGroupData(string header)`: Initializes with header. - **Properties**: - `string Header` - `bool IsVisible` - `ObservableCollection TabDataCollection`: Lazily-initialized collection. - Used to group tabs that appear together under a contextual header. #### `TabData` - **Implements**: `INotifyPropertyChanged` - **Constructors**: - `TabData()`: Calls `this(null)`. - `TabData(string header)`: Initializes with header. - **Properties**: - `string Header` - `string ContextualTabGroupHeader`: Associates tab with a `ContextualTabGroupData`. - `bool IsSelected` - `ObservableCollection GroupDataCollection`: Lazily-initialized collection of 3 `GroupData` instances with default values. #### `GroupData` - **Inherits from**: `ControlData` - **Constructors**: - `GroupData(string header)`: Sets `Label` to `header`. - **Properties**: - `ObservableCollection ControlDataCollection`: Lazily-initialized collection containing 1 each of `Button`, `ToggleButton`, `RadioButton`, `CheckBox`, `TextBox`, `MenuButton`, `SplitButton`, and `ComboBox` instances with default values. #### `RibbonData` - **Implements**: `INotifyPropertyChanged` - **Properties**: - `ObservableCollection TabDataCollection`: Lazily-initialized collection of 4 `TabData` instances. First two tabs are associated with contextual tab groups (`Grp 0`, `Grp 1`), remaining two are non-contextual. - `ObservableCollection ContextualTabGroupDataCollection`: Lazily-initialized collection of 2 `ContextualTabGroupData` instances (`Grp 0`, `Grp 1`), all visible. - `MenuButtonData ApplicationMenuData`: Lazily-initialized application menu button with default values. ### Static Data Provider #### `ViewModelData` - **Namespace**: `DTS.Common.RibbonControl` - **Static Properties**: - `RibbonData RibbonData`: Returns a thread-static instance of `RibbonData`. - `ICommand DefaultCommand`: Returns a `DelegateCommand` that always returns `true` for `CanExecute` and does nothing on `Execute`. - **Internal Constants**: Define default counts for UI elements (e.g., `TabCount = 4`, `ControlCount = 5`, etc.). ## 3. Invariants - All data classes inherit from `ControlData` (except `ContextualTabGroupData` and `RibbonData`), ensuring consistent property set (`Label`, `Command`, `SmallImage`, etc.) across all controls. - `ControlData` properties follow a strict pattern: change detection via reference equality (`==`) before raising `PropertyChanged`. - `ControlDataCollection` properties in `MenuButtonData`, `GroupData`, `GalleryCategoryData`, and `GalleryData` are lazily initialized and populated only once per instance (no re-initialization on subsequent access). - `RibbonData.TabDataCollection` and `ContextualTabGroupDataCollection` are lazily initialized and populated exactly once per instance. - `ViewModelData.RibbonData` uses `[ThreadStatic]`, meaning each thread gets its own independent `RibbonData` instance. - Menu nesting depth is limited to `ViewModelData.MenuItemNestingCount` (value `2`) in `MenuButtonData.ControlDataCollection` via internal `_nestingDepth` tracking. - `IsCheckable` is explicitly set to `true` only for `SplitButtonData` and `SplitMenuItemData` instances in `GroupData` and `MenuButtonData` respectively. - `IsApplicationMenu` flag is propagated through constructors to `MenuButtonData` and its subclasses (`MenuItemData`, `SplitMenuItemData`, etc.) to influence initialization behavior. ## 4. Dependencies ### Internal Dependencies (within module) - All classes reside in `DTS.Common.RibbonControl` namespace. - `ControlData` is the base class for most data classes. - `MenuButtonData` is a base class for `SplitButtonData`, `ComboBoxData`, and `MenuItemData` hierarchy. - `SplitButtonData` is a base class for `SplitMenuItemData` and `ApplicationSplitMenuItemData`. - `MenuItemData` is a base class for `SplitMenuItemData` and `ApplicationMenuItemData`. - `ApplicationMenuItemData` and `ApplicationSplitMenuItemData` extend `MenuItemData` and `SplitMenuItemData` respectively with application-menu-specific semantics. ### External Dependencies - `System.ComponentModel` (`INotifyPropertyChanged`, `PropertyChangedEventArgs`, `DesignerSerializationVisibilityAttribute`) - `System.Windows.Input` (`ICommand`, `DelegateCommand`) - `System.Collections.ObjectModel` (`ObservableCollection`) - `Prism.Commands` (`DelegateCommand`) — used in `ViewModelData.DefaultCommand` - WPF-specific types: `Uri` (for image paths), `DesignerSerializationVisibility` ### What depends on this module - UI rendering layer (not included in source) — consumes these data classes to bind to WPF controls. - Test or design-time code — uses `ViewModelData` to generate sample data. ## 5. Gotchas - **Thread-Safe Data Isolation**: `ViewModelData.RibbonData` uses `[ThreadStatic]`, meaning each thread gets its own `RibbonData` instance. This may cause unexpected behavior if data is expected to be shared across threads. - **Hardcoded Default Values**: Many collections (`GroupData.ControlDataCollection`, `GalleryCategoryData.GalleryItemDataCollection`, etc.) are populated with hardcoded default values (e.g., `"Paste_16x16.png"`, `"ToolTip Title"`). These are not configurable via public API. - **One-Time Initialization**: Collections like `TabData.GroupDataCollection` and `GroupData.ControlDataCollection` are initialized only once. Modifying the collection after first access will not trigger re-initialization, but adding/removing items is allowed. - **Nesting Depth Limitation**: `MenuButtonData.ControlDataCollection` stops populating menu items after `_nestingDepth` reaches `ViewModelData.MenuItemNestingCount` (2). This limit is internal and not exposed. - **`IsCheckable` Not Universal**: Only `SplitButtonData` and `SplitMenuItemData` instances have `IsCheckable = true` set in their default initialization. Regular `ButtonData`, `ToggleButtonData`, etc., do not have this property set (though `ToggleButtonData`, `CheckBoxData`, `RadioButtonData` have `IsChecked`). - **`GalleryData.SelectedItem` Type Mismatch**: The non-generic `GalleryData` uses `GalleryItemData` for `SelectedItem`, while the generic `GalleryData` uses `T`. Ensure type consistency when using the generic variant. - **`ContextualTabGroupHeader` Not Enforced**: `TabData.ContextualTabGroupHeader` is a string property; there is no validation ensuring it matches an actual `ContextualTabGroupData.Header`. - **`Command` Not Used in Default Logic**: While `Command` properties are set to `ViewModelData.DefaultCommand` in default data, there is no logic in these classes to invoke or validate the command. - **No Public Constructors for Generic Types**: Generic classes (`GalleryCategoryData`, `GalleryData`) lack custom constructors, limiting initialization flexibility. None identified from source alone.