Files
DP44/enriched-partialglm/Common/DTS.CommonCore/Themes.md
2026-04-17 14:55:32 -04:00

166 lines
9.9 KiB
Markdown

---
source_files:
- Common/DTS.CommonCore/Themes/CommonStyles.xaml.cs
- Common/DTS.CommonCore/Themes/BrushesAndColors.cs
generated_at: "2026-04-16T12:07:03.479792+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "0e615cefd8a8a763"
---
# Documentation: DTS.Common Themes Module
## 1. Purpose
This module provides centralized access to WPF theme resources (brushes and colors) and event handling for UI tooltips within the DTS application. The `BrushesAndColors` class serves as a cached, static accessor for theme-defined visual resources, eliminating repetitive resource lookups and ensuring consistent styling across the application. The `CommonStyles` partial class bridges UI tooltip events to the application's event aggregation system, enabling decoupled handling of help text display. This module exists to centralize theme management and was refactored (per FB 33034) to consolidate duplicate implementations from the DataPro project.
---
## 2. Public Interface
### CommonStyles (partial class)
**`void ToolTipEventHandler(object sender, System.Windows.Controls.ToolTipEventArgs e)`**
- Handles WPF tooltip events by marking the event as handled and publishing a `HelpTextEvent` via the `IEventAggregator`.
- Retrieves the `IEventAggregator` instance via `ServiceLocator.Current.GetInstance<IEventAggregator>()`.
- Publishes a `HelpTextEventArg` containing the original `sender` and `ToolTipEventArgs`.
---
### BrushesAndColors (abstract class)
All members are static. The class cannot be instantiated.
#### Brush Properties (return `SolidColorBrush` or `Brush`)
| Property Name | Return Type | Resource Key Looked Up |
|---------------|-------------|------------------------|
| `Brush_ApplicationTileExport` | `SolidColorBrush` | `Brush_ApplicationTileExport` |
| `Brush__ApplicationTileCollectData` | `SolidColorBrush` | `Brush_ApplicationTileCollectData` |
| `Brush_ApplicationStatus_Failed` | `SolidColorBrush` | `Brush_ApplicationStatus_Failed` |
| `Brush_Dimmed_Text` | `SolidColorBrush` | `Brush_Dimmed_TextForeground` |
| `Brush_Application_Idle` | `SolidColorBrush` | `Brush_ApplicationStatus_Idle` |
| `Brush_ApplicationStatus_Complete` | `SolidColorBrush` | `Brush_ApplicationStatus_Complete` |
| `Brush_ApplicationStatus_Idle` | `SolidColorBrush` | `Brush_ApplicationStatus_Idle` |
| `Brush_ApplicationStatus_Busy` | `SolidColorBrush` | `Brush_ApplicationStatus_Busy` |
| `Brush_Run_SensorIdNotFound` | `SolidColorBrush` | `Brush_Run_SensorIdNotFound` |
| `Brush_Run_SensorIdOutOfPlace` | `SolidColorBrush` | `Brush_Run_SensorIdOutOfPlace` |
| `Brush_Table_AlternatingRowBackground` | `SolidColorBrush` | `Brush_Table_AlternatingRowBackground` |
| `Brush_Table_RowBackground` | `SolidColorBrush` | `Brush_Table_RowBackground` |
| `Brush_FlatControlPressedBackground` | `Brush` | `Brush_FlatControlPressedBackground` |
| `Brush_FlatControlPressedForeground` | `Brush` | `Brush_FlatControlPressedForeground` |
| `Brush_Transparent` | `Brush` | Creates new `SolidColorBrush(Colors.Transparent)` (no resource lookup) |
| `Brush_NoError` | `Brush` | Loaded from `/DTS.Common;component/Themes/brushes.xaml` |
| `Brush_Error` | `SolidColorBrush` | Loaded from `/DTS.Common;component/Themes/brushes.xaml` |
| `Brush_Warning` | `SolidColorBrush` | Loaded from `/DTS.Common;component/Themes/brushes.xaml` |
| `Brush_Attention` | `SolidColorBrush` | Loaded from `/DTS.Common;component/Themes/brushes.xaml` |
| `Brush_FlatControlDisabledForeground` | `Brush` | `Brush_FlatControlDisabledForeground` |
| `Brush_ApplicationContentForeground` | `Brush` | `Brush_ApplicationContentForeground` |
| `Brush_FlatControlDisabledBackground` | `Brush` | `Brush_FlatControlDisabledBackground` |
| `Brush_ApplicationStatus_Waiting` | `SolidColorBrush` | `Brush_ApplicationStatus_Waiting` |
| `Brush_ApplicationStatus_Failed_ActionBackground` | `SolidColorBrush` | `Brush_ApplicationStatus_Failed_ActionBackground` |
| `Brush_ApplicationStatus_Complete_ActionBackground` | `SolidColorBrush` | `Brush_ApplicationStatus_Complete_ActionBackground` |
| `Brush_ApplicationStatus_Failed_SystemProcess` | `SolidColorBrush` | `Brush_ApplicationStauts_Failed_SystemProcess` (note typo in resource key) |
| `Brush_ApplicationFooterBackground` | `SolidColorBrush` | `Brush_ApplicationFooterBackground` |
| `Brush_ApplicationLicensingFooterBackground` | `SolidColorBrush` | `Brush_ApplicationLicensingFooterBackground` |
| `Brush_Realtime_OSC_SELECTED` | `Brush` | `Brush_Realtime_OSC_SELECTED` |
| `Brush_Realtime_OSC_UNSELECTED` | `Brush` | `Brush_Realtime_OSC_UNSELECTED` |
| `Brush_Realtime_METER_SELECTED` | `Brush` | `Brush_Realtime_METER_SELECTED` |
| `Brush_Realtime_METER_UNSELECTED` | `Brush` | `Brush_Realtime_METER_UNSELECTED` |
| `Brush_SensorIdFound` | `SolidColorBrush` | `Brush_SensorIdFound` |
| `Brush_ArmSystemForeground` | `SolidColorBrush` | `Brush_ArmSystemForeground` |
| `Brush_ApplicationTilePrepare` | `SolidColorBrush` | `Brush_ApplicationTilePrepare` |
| `Brush_ApplicationTileSetup` | `SolidColorBrush` | `Brush_ApplicationTileSetup` |
| `BrushApplicationStatusPowerRed` | `SolidColorBrush` | `Brush_ApplicationStatusPowerRed` |
| `BrushApplicationStatusPowerYellow` | `SolidColorBrush` | `Brush_ApplicationStatusPowerYellow` |
| `BrushApplicationStatusPowerGreen` | `SolidColorBrush` | `Brush_ApplicationStatusPowerGreen` |
| `BrushFlatControlDarkForeground` | `SolidColorBrush` | `Brush_FlatControlDarkForeground` |
| `BrushApplicationStatusPowerClear` | `SolidColorBrush` | `Brush_ApplicationStatusPowerClear` |
#### Color Properties (return `Color`)
These properties perform a direct resource lookup on each call (no caching):
| Property Name | Resource Key |
|---------------|--------------|
| `Color_ActionBackground` | `Color_ActionBackground` |
| `Color_ApplicationTileCollectData` | `Color_ApplicationTileCollectData` |
| `Color_ItemBackground` | `Color_ItemBackground` |
| `Color_ActionForeground` | `Color_ActionForeground` |
| `Color_ItemForeground` | `Color_ItemForeground` |
| `Color_ApplicationTileSetup` | `Color_ApplicationTileSetup` |
| `Color_ApplicationTilePrepare` | `Color_ApplicationTilePrepare` |
| `Color_ApplicationTileCalibration` | `Color_ApplicationTileCalibration` |
| `Color_ApplicationTileExport` | `Color_ApplicationTileExport` |
| `Color_ApplicationTileAdmin` | `Color_ApplicationTileAdmin` |
---
## 3. Invariants
1. **Brush Caching**: All brush properties use lazy initialization with null-check guards. Once a brush is retrieved and frozen, the same instance is returned on subsequent calls.
2. **Brush Freezing**: All retrieved brushes are frozen via `.Freeze()` before being returned, making them thread-safe and non-modifiable.
3. **Application Resource Availability**: All brush/color properties (except `Brush_Transparent`, `Brush_NoError`, `Brush_Error`, `Brush_Warning`, `Brush_Attention`) require `Application.Current` to be available and the named resource to exist in the application's resource dictionary.
4. **ServiceLocator Availability**: `CommonStyles.ToolTipEventHandler` requires `ServiceLocator.Current` to be configured and able to resolve `IEventAggregator`.
5. **Event Handling**: `ToolTipEventHandler` always sets `e.Handled = true` before publishing the event.
---
## 4. Dependencies
### This module depends on:
- `System.Windows` - For `Application`, `ResourceDictionary`, `Brush`, `SolidColorBrush`, `Colors`, `Color`
- `System.Windows.Controls` - For `ToolTipEventArgs`
- `Microsoft.Practices.ServiceLocation` - For `ServiceLocator`
- `Microsoft.Practices.Prism.Events` - For `IEventAggregator`
- `DTS.Common.Events` - For `HelpTextEvent` and `HelpTextEventArg`
- External XAML resource files: `/DTS.Common;component/Themes/brushes.xaml`
- Application-level resource dictionary containing all named brush/color resources
### What depends on this module:
- Unclear from source alone. Consumers would be any UI code requiring consistent access to theme brushes/colors, and any XAML that attaches `ToolTipEventHandler` to tooltip events.
---
## 5. Gotchas
### Critical Bugs
1. **`Brush_Warning` is broken**: The property getter assigns to `_brushError` instead of `_brushWarning`:
```csharp
_brushError = (SolidColorBrush)_resourceDictionary["Brush_Warning"];
```
This corrupts `Brush_Error` and `Brush_Warning` will always return `null` (or throw if the readonly field prevents assignment—unclear if this compiles).
2. **`_brushWarning` is declared `readonly` but assigned**: The field is declared as:
```csharp
private static readonly SolidColorBrush _brushWarning = null;
```
This will cause a compile error when the property attempts to assign to it.
### Naming Inconsistencies
3. **Double underscore in property name**: `Brush__ApplicationTileCollectData` has two underscores between "Brush" and "Application"—likely a typo.
4. **Typo in resource key**: `Brush_ApplicationStatus_Failed_SystemProcess` looks up `Brush_ApplicationStauts_Failed_SystemProcess` (misspelled "Stauts").
### Theme Switching Limitation
5. **Stale brushes after theme change**: As documented in the class comment, cached brushes become stale if themes are switched at runtime. The comment states: *"this class is holding static caches of the brushes, so if we switch themes they might be out of date"*. There is no mechanism to clear or refresh the cache.
### Inconsistent Null-Checking Patterns
6. **Mixed null-check styles**: Some properties check `if (null == _field)` while others check `if (null != _field) return _field`. This inconsistency makes the code harder to maintain.
7. **Inconsistent null-safety on Freeze()**: Some properties call `.Freeze()` unconditionally (will throw if resource not found), while others check for null before freezing:
```csharp
if (_brushApplicationStatusPowerRed != null) _brushApplicationStatusPowerRed.Freeze();
```
### Performance Note
8. **Color properties are not cached**: Unlike brush properties, all `Color_*` properties perform a resource lookup on every access via `Application.Current.FindResource()`.