--- source_files: - Common/DTS.CommonCore/RibbonControl/Classes/ButtonData.cs - Common/DTS.CommonCore/RibbonControl/Classes/SeparatorData.cs - Common/DTS.CommonCore/RibbonControl/Classes/GalleryItemData.cs - Common/DTS.CommonCore/RibbonControl/Classes/ComboBoxData.cs - Common/DTS.CommonCore/RibbonControl/Classes/MenuItemData.cs - Common/DTS.CommonCore/RibbonControl/Classes/SplitMenuItemData.cs - Common/DTS.CommonCore/RibbonControl/Classes/ApplicationMenuItemData.cs - Common/DTS.CommonCore/RibbonControl/Classes/ApplicationSplitMenuItemData.cs - Common/DTS.CommonCore/RibbonControl/Classes/TextBoxData.cs - Common/DTS.CommonCore/RibbonControl/Classes/CheckBoxData.cs - Common/DTS.CommonCore/RibbonControl/Classes/RadioButtonData.cs - Common/DTS.CommonCore/RibbonControl/Classes/ToggleButtonData.cs - Common/DTS.CommonCore/RibbonControl/Classes/SplitButtonData.cs - Common/DTS.CommonCore/RibbonControl/Classes/ContextualTabGroupData.cs - Common/DTS.CommonCore/RibbonControl/Classes/ViewModel.cs - Common/DTS.CommonCore/RibbonControl/Classes/GalleryCategoryData.cs - Common/DTS.CommonCore/RibbonControl/Classes/TabData.cs - Common/DTS.CommonCore/RibbonControl/Classes/RibbonData.cs - Common/DTS.CommonCore/RibbonControl/Classes/GalleryData.cs - Common/DTS.CommonCore/RibbonControl/Classes/ControlData.cs - Common/DTS.CommonCore/RibbonControl/Classes/MenuButtonData.cs - Common/DTS.CommonCore/RibbonControl/Classes/GroupData.cs generated_at: "2026-04-16T02:47:59.133790+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "8f96fa689f5431a2" --- # RibbonControl Data Model Documentation ## 1. Purpose This module defines a hierarchical data model for representing ribbon UI controls in a WPF application. It provides a set of data classes (`*Data`) that serve as view models for UI elements in a ribbon interface, enabling declarative construction of ribbon structures (tabs, groups, controls) with support for commands, images, tooltips, and dynamic state. The model supports standard controls (buttons, checkboxes, text boxes), menu-based controls (menu buttons, split buttons, menu items), and specialized controls (galleries, combo boxes), with built-in support for application menu structures and contextual tab groups. It is part of the `DTS.Common.RibbonControl` namespace and is intended to be consumed by UI rendering layers that bind to these data objects. ## 2. Public Interface All classes are `public` and reside in the `DTS.Common.RibbonControl` namespace. Most implement `INotifyPropertyChanged`. ### Base Classes - **`ControlData`** Base class for all ribbon control data models. Provides common 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 : ControlData`** Base class for controls that can host child controls (e.g., menu buttons, split buttons). Constructor accepts `bool isApplicationMenu`. Provides: `bool IsVerticallyResizable`, `bool IsHorizontallyResizable`, `ObservableCollection ControlDataCollection` (lazy-initialized with sample content based on `ViewModelData` constants). Internally tracks `_nestingDepth` to limit recursive menu nesting. - **`SplitButtonData : MenuButtonData`** Extends `MenuButtonData`. Adds: `bool IsChecked`, `bool IsCheckable`, `ButtonData DropDownButtonData` (lazy-initialized). Used for split buttons with a main action and dropdown. ### Leaf Controls - **`ButtonData : ControlData`** Simple button control. - **`SeparatorData : ControlData`** Visual separator control. - **`GalleryItemData : ControlData`** Item within a gallery. - **`TextBoxData : ControlData`** Text input control. Adds: `string Text` (raises `PropertyChanged` on change). - **`CheckBoxData : ControlData`** Check box control. Adds: `bool IsChecked` (raises `PropertyChanged` on change). - **`RadioButtonData : ControlData`** Radio button control. Adds: `bool IsChecked` (raises `PropertyChanged` on change). - **`ToggleButtonData : ControlData`** Toggle button control. Adds: `bool IsChecked` (raises `PropertyChanged` on change). ### Menu Hierarchy - **`MenuItemData : SplitButtonData`** Menu item. Constructor accepts optional `bool isApplicationMenu`. Used for standard menu items. - **`SplitMenuItemData : MenuItemData`** Split menu item. Constructor accepts optional `bool isApplicationMenu`. - **`ApplicationMenuItemData : MenuItemData`** Menu item specifically for the application menu. Constructor accepts optional `bool isApplicationMenu`. - **`ApplicationSplitMenuItemData : SplitMenuItemData`** Split menu item for the application menu. Constructor accepts optional `bool isApplicationMenu`. - **`ComboBoxData : MenuButtonData`** Combo box control (inherits from `MenuButtonData`, not `ControlData`). ### Container Classes - **`GalleryCategoryData : ControlData`** Category within a gallery. Provides: `ObservableCollection GalleryItemDataCollection` (lazy-initialized with 10 items per `ViewModelData.GalleryItemCount`, pre-populated with sample data including `ViewModelData.DefaultCommand`). *Generic variant*: `GalleryCategoryData` provides `ObservableCollection GalleryItemDataCollection`. - **`GalleryData : ControlData`** Gallery control. Provides: `ObservableCollection CategoryDataCollection` (lazy-initialized with 3 categories per `ViewModelData.GalleryCategoryCount`, each with sample data), `GalleryItemData SelectedItem`, `bool CanUserFilter`. *Generic variant*: `GalleryData` provides `ObservableCollection> CategoryDataCollection`, `T SelectedItem`, `bool CanUserFilter`. - **`GroupData : ControlData`** Ribbon group. Constructor takes `string header`. Provides: `ObservableCollection ControlDataCollection` (lazy-initialized with sample controls: 1 `ButtonData`, 1 `ToggleButtonData`, 1 `RadioButtonData`, 1 `CheckBoxData`, 1 `TextBoxData`, 1 `MenuButtonData`, 1 `SplitButtonData`, 1 `ComboBoxData`, per `ViewModelData` constants). - **`TabData : INotifyPropertyChanged`** Ribbon tab. Constructor takes optional `string header`. Provides: `string Header`, `string ContextualTabGroupHeader`, `bool IsSelected`, `ObservableCollection GroupDataCollection` (lazy-initialized with 3 groups per `ViewModelData.GroupCount`). - **`ContextualTabGroupData : INotifyPropertyChanged`** Contextual tab group container. Constructor takes optional `string header`. Provides: `string Header`, `bool IsVisible`, `ObservableCollection TabDataCollection`. - **`RibbonData : INotifyPropertyChanged`** Top-level ribbon model. Provides: `ObservableCollection TabDataCollection` (lazy-initialized with 4 tabs; first 2 assigned to contextual tab groups), `ObservableCollection ContextualTabGroupDataCollection` (lazy-initialized with 2 groups), `MenuButtonData ApplicationMenuData` (lazy-initialized with sample data and `isApplicationMenu=true`). ### Static ViewModel Provider - **`ViewModelData`** Static class providing: - `internal const int` constants defining default counts for various control types (e.g., `TabCount = 4`, `ButtonCount = 1`, `GalleryItemCount = 10`, etc.). - `RibbonData RibbonData` (thread-static singleton). - `ICommand DefaultCommand` (a `DelegateCommand` that always `CanExecute` and does nothing in `Execute`). ## 3. Invariants - **Control hierarchy constraints**: - `RibbonData` contains `TabData` instances, each of which belongs to a `ContextualTabGroupData` (via `ContextualTabGroupHeader`) or none. - `TabData` contains `GroupData` instances. - `GroupData` contains `ControlData` instances (including derived types). - `MenuButtonData` and its descendants (`SplitButtonData`, `ComboBoxData`, `MenuItemData`, etc.) may contain nested `ControlData` instances. - `GalleryData` contains `GalleryCategoryData`, which contains `GalleryItemData`. - Nesting depth for menu items is limited to `ViewModelData.MenuItemNestingCount` (2) in `MenuButtonData.ControlDataCollection` initialization. - **Initialization behavior**: - Collections (`TabDataCollection`, `GroupDataCollection`, `ControlDataCollection`, `CategoryDataCollection`, etc.) are lazily initialized on first access and reused thereafter. - Sample data (images, labels, tooltips) in collections is hardcoded using `/Common;component/RibbonControl/Images/Paste_16x16.png` and `Paste_32x32.png` URIs. - `RibbonData.TabDataCollection` inserts tabs in reverse order (`i` from `TabCount` down to 1) to ensure correct visual ordering. - **Property change notifications**: - All properties in `ControlData` and derived classes raise `PropertyChanged` only when the new value differs from the current value (except `GalleryData.SelectedItem`, which uses `Equals` for comparison). - `RibbonData`, `TabData`, `ContextualTabGroupData` implement `INotifyPropertyChanged` and raise events for their properties. - **Application menu flag**: - The `isApplicationMenu` constructor parameter is passed down through `MenuItemData`, `SplitMenuItemData`, `ApplicationMenuItemData`, `ApplicationSplitMenuItemData`, and `MenuButtonData` to influence initialization logic (e.g., which `*Data` types are instantiated in `ControlDataCollection`). ## 4. Dependencies ### Internal Dependencies (within module) - **`ViewModelData`**: Used by `GalleryCategoryData`, `GalleryData`, `MenuButtonData`, `GroupData`, `RibbonData` to populate collections with default counts and sample data. - **`ViewModelData.DefaultCommand`**: Used as the default `Command` for sample controls. - **`ViewModelData` constants**: Drive initialization logic in `GalleryCategoryData`, `GalleryData`, `MenuButtonData`, `GroupData`, `RibbonData`. ### External Dependencies - **`System`**, **`System.Collections.ObjectModel`**, **`System.ComponentModel`**, **`System.Windows.Input`**: Standard .NET libraries for collections, property change notifications, and commands. - **`Microsoft.Practices.Prism.Commands`**: Used for `DelegateCommand` in `ViewModelData.DefaultCommand`. - **WPF image URIs**: Hardcoded URIs like `/Common;component/RibbonControl/Images/Paste_16x16.png` imply dependencies on embedded resources in the `Common` assembly. ### Inferred Usage - This module is intended to be used by UI rendering layers (e.g., XAML views) that bind to `RibbonData`, `TabData`, `GroupData`, and `ControlData` instances. - `RibbonData` is the primary entry point for ribbon configuration. ## 5. Gotchas - **Thread-static singleton**: `ViewModelData.RibbonData` is `[ThreadStatic]`, meaning each thread gets its own instance. This may cause unexpected behavior if ribbon data is shared across threads without synchronization. - **Hardcoded image paths**: URIs like `/Common;component/RibbonControl/Images/Paste_16x16.png` assume specific resource paths and assembly names. Changes to resource structure will break sample data. - **Nesting depth limit**: `MenuButtonData.ControlDataCollection` stops adding nested items after `_nestingDepth` reaches `ViewModelData.MenuItemNestingCount` (2). This limit is not exposed or configurable. - **`ComboBoxData` inheritance**: `ComboBoxData` inherits from `MenuButtonData`, not `ControlData`. This may be non-intuitive and implies it has `ControlDataCollection` and `IsVerticallyResizable`/`IsHorizontallyResizable` properties. - **`SplitButtonData` vs `SplitMenuItemData`**: Both have `IsCheckable` and `IsChecked`, but `SplitButtonData` is a leaf control in groups, while `SplitMenuItemData` is part of a menu hierarchy. Their behaviors may differ contextually. - **`GalleryData.SelectedItem` type mismatch**: Non-generic `GalleryData.SelectedItem` is `GalleryItemData`, while generic `GalleryData.SelectedItem` is `T`. Ensure type consistency when using the generic variant. - **`ControlData` vs `ControlDataCollection`**: `ControlDataCollection` is initialized only once per instance and reused. Modifying the collection after first access may have side effects if other code expects a fixed structure. - **No validation**: No validation is performed on property values (e.g., `Label`, `KeyTip`, `Header`). Invalid values may cause UI rendering issues. - **`IsApplicationMenu` flag propagation**: The `isApplicationMenu` flag is passed to constructors but only used in `MenuButtonData` initialization logic. Its effect on `MenuItemData`/`SplitMenuItemData` descendants is not evident from the source (they all accept the parameter but do not store or use it beyond base constructor calls).