--- source_files: - Common/DTS.CommonCore/Themes/CommonStyles.xaml.cs - Common/DTS.CommonCore/Themes/BrushesAndColors.cs generated_at: "2026-04-16T02:17:03.753064+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "0e615cefd8a8a763" --- # Themes ## Documentation: `DTS.Common` Theme & Style Utilities --- ### 1. Purpose This module provides shared, reusable styling infrastructure for the application’s UI, specifically focusing on two concerns: (1) centralized access to theme-defined `Brush` and `Color` resources via static properties with caching to avoid repeated resource lookups, and (2) a centralized event handler for tooltip events that publishes help text via Prism’s `IEventAggregator`. It serves as a single source of truth for visual styling constants, decoupling UI components from explicit resource key strings and enabling consistent theming across the application. The module does *not* define styles itself but consumes them from external resource dictionaries (e.g., `brushes.xaml` and implicit theme dictionaries). --- ### 2. Public Interface #### `CommonStyles` (partial class, non-static) - **`void ToolTipEventHandler(object sender, ToolTipEventArgs e)`** Marks the tooltip event as handled (`e.Handled = true`) and publishes a `HelpTextEventArg` instance (containing the original `sender` and `ToolTipEventArgs`) to the `HelpTextEvent` via the `IEventAggregator`. This enables decoupled help-text display logic elsewhere in the application. #### `BrushesAndColors` (abstract, non-instantiable) A static utility class exposing ~40 read-only properties returning cached `Brush` or `Color` resources. All properties follow the naming pattern `Brush_*` or `Color_*`. Key examples: - **`Brush_ApplicationTileExport`** → `SolidColorBrush` - **`Brush_ApplicationStatus_Failed`** → `SolidColorBrush` - **`Brush_Dimmed_Text`** → `SolidColorBrush` - **`Brush_Table_AlternatingRowBackground`** → `SolidColorBrush` - **`Brush_FlatControlPressedBackground`** → `Brush` - **`Brush_Transparent`** → `Brush` (created on-demand as `new SolidColorBrush(Colors.Transparent)`) - **`Brush_Error`**, **`Brush_Warning`**, **`Brush_Attention`**, **`Brush_NoError`** → `SolidColorBrush` - **`Brush_Realtime_OSC_SELECTED`**, **`Brush_Realtime_METER_UNSELECTED`**, etc. → `Brush` - **`Brush_ApplicationStatusPowerRed`**, **`Brush_ApplicationStatusPowerYellow`**, **`Brush_ApplicationStatusPowerGreen`** → `SolidColorBrush` - **`Color_ActionBackground`**, **`Color_ItemForeground`**, etc. → `Color` (not cached; fetched fresh each call) > **Note**: Properties are implemented with lazy initialization and caching (where applicable). The `BrushesAndColors` class is `abstract` to prevent instantiation. --- ### 3. Invariants - **Resource Availability**: All `Brush`/`Color` resources must be defined in the application’s resource dictionaries (e.g., `Themes/brushes.xaml` or merged dictionaries). If a resource is missing, `Application.Current.FindResource(...)` will throw a `ResourceReferenceKeyNotFoundException` at runtime (not caught in the source). - **Immutability**: All retrieved `Brush` instances are frozen (`Freeze()`) to make them immutable and thread-safe for rendering. This is enforced via `.Freeze()` after retrieval. - **Caching Semantics**: - Most `Brush` properties cache their value in a private static field and reuse it on subsequent calls. - `Color` properties do *not* cache; they call `Application.Current.FindResource(...)` every time. - The `_resourceDictionary` field is shared across all resource lookups that fall back to `brushes.xaml`, but is only initialized on first use for those specific properties. - **Null Safety**: Some properties guard against null resources (e.g., `Brush_FlatControlDisabledForeground`, `Brush_ApplicationStatus_Waiting`) and return `null` if the resource is missing. Others do not (e.g., `Brush_Error`), risking exceptions. --- ### 4. Dependencies #### External Dependencies (Imports/Usings) - **`System.Windows`** → WPF core types (`Application`, `ResourceDictionary`, `Brush`, `SolidColorBrush`, `Colors`). - **`System.Windows.Controls`** → `ToolTipEventArgs`. - **`Microsoft.Practices.ServiceLocation`** → `ServiceLocator.Current`. - **`Microsoft.Practices.Prism.Events`** → `IEventAggregator`, `IEvent`. - **`DTS.Common.Events`** → `HelpTextEvent`, `HelpTextEventArg` (consumed but not defined here). #### Internal Dependencies - **`DTS.Common.Events.HelpTextEvent`** and **`HelpTextEventArg`** must be defined elsewhere in `DTS.Common.Events`. - **`Themes/brushes.xaml`** → Required resource dictionary for fallback lookups (used by `Brush_NoError`, `Brush_Error`, `Brush_Warning`, `Brush_Attention`). - **Application-level resource dictionaries** → Must define all referenced resource keys (e.g., `"Brush_ApplicationStatus_Failed"`, `"Color_ActionBackground"`, etc.). #### Consumers (Inferred) - Any UI component needing consistent styling (e.g., tiles, tables, status indicators) likely references `BrushesAndColors` properties directly in XAML or code-behind. - Any component needing help-text support on tooltips likely subscribes to `HelpTextEvent` and attaches `CommonStyles.ToolTipEventHandler` to tooltip events. --- ### 5. Gotchas - **Theme Switching Incompatibility**: As noted in the `BrushesAndColors` XML doc comment, static caching means brushes may become stale if the theme changes at runtime (e.g., via dynamic resource dictionary replacement). The comment suggests this is currently non-issue because themes are not actively used. - **Inconsistent Caching Strategy**: `Color` properties do *not* cache, while most `Brush` properties do. This is likely unintentional and could lead to repeated resource lookups for colors. - **Typo in Resource Key**: In `Brush_ApplicationStatus_Failed_SystemProcess`, the resource key is `"Brush_ApplicationStauts_Failed_SystemProcess"` (missing "a" in "Status"). This may cause runtime failures if the key is misspelled in the XAML resource dictionary. - **Null Handling Inconsistency**: Some properties (e.g., `Brush_FlatControlDisabledForeground`) return `null` if the resource is missing; others (e.g., `Brush_Error`) do not check for null after `FindResource`, risking exceptions. - **Double Initialization Risk in `Brush_Warning`**: The `Brush_Warning` property incorrectly assigns to `_brushError` instead of `_brushWarning` in its getter (`_brushError = ...`). This is a bug: it overwrites the `_brushError` cache and returns the warning brush as `_brushError`, while `_brushWarning` remains `null`. - **Thread Safety**: While frozen brushes are thread-safe, the lazy initialization logic (e.g., `if (null == _brush_X) ...`) is *not* thread-safe. Concurrent access during first initialization could result in multiple lookups or race conditions. - **Hardcoded Resource Paths**: The fallback `ResourceDictionary` for `Brush_NoError`, `Brush_Error`, etc., uses a hardcoded pack URI (`/DTS.Common;component/Themes/brushes.xaml`). This assumes the dictionary is embedded as a resource in the `DTS.Common` assembly. > **None identified from source alone** — *except where explicitly called out above.*