197 lines
16 KiB
Markdown
197 lines
16 KiB
Markdown
|
|
---
|
||
|
|
source_files:
|
||
|
|
- DataPRO/Modules/PreviousDBVersions/Version57/DatabaseExport/Classes/RegionsAndZones/Zone.cs
|
||
|
|
- DataPRO/Modules/PreviousDBVersions/Version57/DatabaseExport/Classes/RegionsAndZones/RegionAdorner.cs
|
||
|
|
- DataPRO/Modules/PreviousDBVersions/Version57/DatabaseExport/Classes/RegionsAndZones/Region.cs
|
||
|
|
generated_at: "2026-04-16T04:59:50.772455+00:00"
|
||
|
|
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||
|
|
schema_version: 1
|
||
|
|
sha256: "086bec3733d0d7e4"
|
||
|
|
---
|
||
|
|
|
||
|
|
# Documentation: `Region` and `Zone` Classes (DatabaseExport Module, Version 57)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 1. Purpose
|
||
|
|
|
||
|
|
This module provides data structures and UI adorning logic for representing and manipulating *regions* and *zones* within medical imaging test object templates, conforming to ISO 13499 standards. The `Zone` class encapsulates a named area of an image (with optional picture, description, and associated regions), while the `Region` class defines a rectangular sub-region with associated MME (Medical Monitoring Equipment) metadata (e.g., direction, filter class, transducer location). The `RegionAdorner` class enables interactive drawing and manipulation of regions on WPF `Image` elements. Together, they support editing, serialization, and ISO-compliant code generation for test object configurations.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. Public Interface
|
||
|
|
|
||
|
|
### `Zone` Class (`Zone.cs`)
|
||
|
|
|
||
|
|
| Member | Signature | Description |
|
||
|
|
|--------|-----------|-------------|
|
||
|
|
| **Constructor** | `Zone(TemplateZone z, TestObjectTemplate template)` | Initializes a `Zone` from a `TemplateZone` and `TestObjectTemplate`. Loads picture, sets description, and constructs `Region` objects from `z.TemplateRegions`. |
|
||
|
|
| `Name` | `string Name { get; set; }` | Gets or sets the zone name (from `z.ZoneName`). |
|
||
|
|
| `Description` | `string Description { get; set; }` | Gets or sets the zone description (from `z.Description`; defaults to `""` if null). |
|
||
|
|
| `Image` | `string Image { get; set; }` | Gets or sets the picture filename (from `z.Picture`). |
|
||
|
|
| `ISODllZone` | `TemplateZone ISODllZone { get; }` | Immutable reference to the underlying `TemplateZone` object. |
|
||
|
|
| `AllPictures` | `string[] AllPictures { get; }` | Returns an alphabetically sorted array of all picture filenames (by `FileInfo.FullName`) in the `"ZonePictures"` subdirectory of `AppDomain.CurrentDomain.BaseDirectory`. |
|
||
|
|
| `PictureIndex` | `int PictureIndex { get; set; }` | Gets or sets the index of the currently selected picture in `AllPictures`. Setting to `< 0` clears `PictureSource`; otherwise, loads and sets `BitmapImage` from `_fileNames[value].FullName`. |
|
||
|
|
| `GetPictureName()` | `string GetPictureName()` | Returns the filename of the picture at `_pictureIndex`, or `""` if `_pictureIndex < 0`. |
|
||
|
|
| `PictureSource` | `System.Windows.Media.ImageSource PictureSource { get; set; }` | Gets or sets the WPF `ImageSource` for the currently selected picture. Initialized to `null`. |
|
||
|
|
| `Regions` | `Region[] Regions { get; set; }` | Gets or sets the array of `Region` objects associated with this zone. Internally stored as `List<Region>`. |
|
||
|
|
|
||
|
|
#### Nested Type: `FileInfoComparer`
|
||
|
|
| Member | Signature | Description |
|
||
|
|
|--------|-----------|-------------|
|
||
|
|
| `Compare` | `int IComparer<FileInfo>.Compare(FileInfo left, FileInfo right)` | Compares two `FileInfo` objects by `FullName`. Handles `null` inputs (`null < non-null`). |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### `Region` Class (`Region.cs`)
|
||
|
|
|
||
|
|
| Member | Signature | Description |
|
||
|
|
|--------|-----------|-------------|
|
||
|
|
| **Constructors** | `Region(RegionAdorner adorner, TestObjectTemplate template)`<br>`Region(TestObjectTemplate template, TemplateRegion r)` | First: Creates a *new* region (e.g., for drawing), initializes defaults (`"New region"`, `"Describe region"`), and populates ISO settings from `template`.<br>Second: Loads region from persisted `TemplateRegion` (e.g., deserialization), including coordinates, ISO codes, and filters channels. |
|
||
|
|
| `RegionName` | `string RegionName { get; set; }` | Gets or sets the region name. Triggers `InvalidateVisual()` on change. |
|
||
|
|
| `RegionDescription` | `string RegionDescription { get; set; }` | Gets or sets the region description. Triggers `InvalidateVisual()` on change. |
|
||
|
|
| `RegionUpperLeft` | `Point RegionUpperLeft { get; set; }` | Gets or sets the upper-left coordinate of the region (WPF `Point`, in pixel space). |
|
||
|
|
| `RegionBottomRight` | `Point RegionBottomRight { get; set; }` | Gets or sets the bottom-right coordinate of the region (WPF `Point`, in pixel space). |
|
||
|
|
| `RegionDirection` | `MMEDirections RegionDirection { get; set; }` | Gets or sets the direction (e.g., `"A"`, `"S"`, `"?"`). Triggers `SetISOCode()`. |
|
||
|
|
| `RegionFilterClass` | `MMEFilterClasses RegionFilterClass { get; set; }` | Gets or sets the filter class. Updates `_filterClassIndex` and triggers `SetISOCode()`. |
|
||
|
|
| `RegionFineLocation1/2/3` | `MMEFineLocations1/2/3 RegionFineLocation1/2/3 { get; set; }` | Gets or sets fine location properties. Each triggers `SetISOCode()`. |
|
||
|
|
| `RegionMainLocation` | `MMETransducerMainLocation RegionMainLocation { get; set; }` | Gets or sets the main transducer location. Triggers `SetISOCode()`. |
|
||
|
|
| `RegionPhysicalDimension` | `MMEPhysicalDimensions RegionPhysicalDimension { get; set; }` | Gets or sets the physical dimension (e.g., `"mm"`, `"??"`). Triggers `SetISOCode()`. |
|
||
|
|
| `RegionPosition` | `MMEPositions RegionPosition { get; set; }` | Gets or sets the position (e.g., `"P1"`, `"?"`). Triggers `SetISOCode()`. |
|
||
|
|
| `RegionTestObject` | `MMETestObjects RegionTestObject { get; set; }` | Gets or sets the associated test object (from ISO code or template). |
|
||
|
|
| `RegionChannels` | `TestObjectTemplateChannel[] RegionChannels { get; set; }` | Gets or sets the list of channels *filtered* by current region settings. Setting triggers `DetermineAvailableISOSettings()`. |
|
||
|
|
| `RegionUIChannels` | `TemplateChannelUI[] RegionUIChannels { get; set; }` | Gets or sets the UI channel list corresponding to `RegionChannels`. |
|
||
|
|
| `ISOCode` | `string ISOCode { get; set; }` | Gets or sets the 16-character ISO code (e.g., `"A1B2C3D4E5F6G7H8"`). Computed from `SetISOCode()` using all region properties. |
|
||
|
|
| `AllDirections`, `AllFilterClasses`, `AllFineLocations1/2/3`, `AllMainLocations`, `AllPhysicalDimensions`, `AllPositions` | `T[] AllX { get; set; }` | Arrays of available ISO enum values (e.g., `MMEDirections[]`). Each has a corresponding `AllXStrings` property (e.g., `string[] AllDirectionsStrings`). Setting populates the string array from `Text_L1` (or `"?"`, `"??"`, `"????"` for nulls). |
|
||
|
|
| `AllDirectionsStrings`, `AllFilterClassStrings`, `AllFineLocations1Strings`, `AllFineLocations2Strings`, `AllFineLocations3Strings`, `AllMainLocationsStrings`, `AllPhysicalDimensionStrings`, `AllPositionStrings` | `string[] AllXStrings { get; set; }` | String representations of the corresponding enum arrays. |
|
||
|
|
| `RegionAddVisibility` | `Visibility RegionAddVisibility { get; set; }` | Gets or sets UI visibility for "add region" controls. Default: `Visible`. |
|
||
|
|
| `RegionDeleteVisibility` | `Visibility RegionDeleteVisibility { get; set; }` | Gets or sets UI visibility for "delete region" controls. Default: `Hidden`. |
|
||
|
|
| `Template` | `TestObjectTemplate Template { get; set; }` | Gets or sets the parent template. Setting triggers `DetermineAvailableISOSettings()`. |
|
||
|
|
| `ToISORegion(TestObjectTemplate, Zone, int)` | `TemplateRegion ToISORegion(TestObjectTemplate template, Zone zone, int number)` | Serializes this `Region` to a `TemplateRegion` object, converting `Point` coordinates to `System.Drawing.Point` and handling nulls with ISO defaults (`"?"`, `"??"`, etc.). |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### `RegionAdorner` Class (`RegionAdorner.cs`)
|
||
|
|
|
||
|
|
| Member | Signature | Description |
|
||
|
|
|--------|-----------|-------------|
|
||
|
|
| **Constructor** | `RegionAdorner(UIElement adornedElement, TestObjectTemplate template, Contexts context)` | Creates a new adorner for an `Image`. Initializes `_region`, `SelectRect`, `_geometry`, and `_path` (blue, semi-transparent stroke). Attaches mouse event handlers. |
|
||
|
|
| `GetUpperLeft()` | `Point GetUpperLeft()` | Returns the *upper-left* point of `SelectRect`, adjusted for image scaling (difference between `RenderSize` and `Source` dimensions). |
|
||
|
|
| `GetLowerRight()` | `Point GetLowerRight()` | Returns the *lower-right* point of `SelectRect`, similarly scaled. Returns `(0,0)` if `AdornedElement.Source` is `null`. |
|
||
|
|
| `IsNew` | `bool IsNew { get; set; }` | Gets or sets whether this adorner represents a *new* region being drawn. Updates `RegionAddVisibility`/`RegionDeleteVisibility` accordingly. |
|
||
|
|
| `AnchorPoint` | `Point AnchorPoint { get; set; }` | Gets or sets the starting point for drawing (set on `MouseDown`). |
|
||
|
|
| `SelectRect` | `Rect SelectRect { get; set; }` | Gets or sets the current selection rectangle. Updates `MyRegion.RegionUpperLeft`/`RegionBottomRight` via `GetUpperLeft()`/`GetLowerRight()`. |
|
||
|
|
| `MyRegion` | `Region MyRegion { get; set; }` | Gets or sets the associated `Region` instance. |
|
||
|
|
| `Context` | `Contexts Context { get; set; }` | Gets or sets the editing context (`EditTestObject` or `EditTestObjectTemplate`). |
|
||
|
|
| `OnRegionSelected` | `event RegionSelectedHandler OnRegionSelected` | Event raised on `MouseLeftButtonDown`. |
|
||
|
|
| `OnEndSelection` | `event EndSelectionHandler OnEndSelection` | Event raised on `MouseLeftButtonUp` (after `EndSelection()`). |
|
||
|
|
| `Region_MouseMove` | `void Region_MouseMove(...)` | Handles mouse drag: calls `DrawSelection()` (if `IsNew`) or `MoveSelection()` (if editing). Invalidates visuals. |
|
||
|
|
| `DrawSelection` | `void DrawSelection(...)` | Updates `SelectRect` to a rectangle between `AnchorPoint` and current mouse position. |
|
||
|
|
| `MoveSelection` | `void MoveSelection(...)` | Moves `SelectRect` by the delta from the previous mouse position (`p1`). |
|
||
|
|
| `EndSelection` | `void EndSelection(...)` | Releases mouse capture and raises `OnEndSelection`. |
|
||
|
|
|
||
|
|
#### Nested Type: `Contexts`
|
||
|
|
| Value | Description |
|
||
|
|
|-------|-------------|
|
||
|
|
| `EditTestObject` | Context for editing a specific test object instance. |
|
||
|
|
| `EditTestObjectTemplate` | Context for editing a reusable template. |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. Invariants
|
||
|
|
|
||
|
|
- **`Zone`**:
|
||
|
|
- `Description` is never `null`; defaults to `""` if `z.Description` is `null`.
|
||
|
|
- `Image` is set from `z.Picture`; if non-empty, the code attempts to load the image from `"ZonePictures/{Image}"`.
|
||
|
|
- `PictureIndex` is `-1` if the image file does not exist or fails to load (e.g., invalid format).
|
||
|
|
- `Regions` is always initialized as a `List<Region>`; populated from `z.TemplateRegions` in the constructor.
|
||
|
|
|
||
|
|
- **`Region`**:
|
||
|
|
- `ISOCode` is always 16 characters (uses `"?"`, `"??"`, `"????"` for null/missing values).
|
||
|
|
- `RegionChannels` and `RegionUIChannels` are filtered based on current ISO settings (direction, filter class, fine locations, etc.) via `FilterRegionChannels()`.
|
||
|
|
- `DetermineAvailableISOSettings()` ensures that each enum property (e.g., `RegionDirection`) includes a wildcard option (`"?"`, `"??"`) in its `AllX` array.
|
||
|
|
- `RegionTestObject` is set from the first distinct test object in `RegionChannels` during `DetermineAvailableISOSettings()`.
|
||
|
|
|
||
|
|
- **`RegionAdorner`**:
|
||
|
|
- `SelectRect` is always synchronized with `MyRegion.RegionUpperLeft`/`RegionBottomRight`.
|
||
|
|
- Scaling adjustments in `GetUpperLeft()`/`GetLowerRight()` assume the `AdornedElement` is an `Image` with a `Source` of known dimensions.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. Dependencies
|
||
|
|
|
||
|
|
### Imports/References (from source):
|
||
|
|
- **WPF namespaces**: `System.Windows.*` (`Adorner`, `Image`, `MouseEventArgs`, `Point`, `Rect`, `Visibility`, `Brushes`, `Path`, `RectangleGeometry`, `ImageSource`, `BitmapImage`).
|
||
|
|
- **System.IO**: `AppDomain`, `Directory`, `Path`, `FileInfo`.
|
||
|
|
- **Custom types** (inferred from usage):
|
||
|
|
- `TestObjectTemplate`, `TemplateRegion`, `TemplateZone`, `TestObjectTemplateChannel`, `TemplateChannelUI`
|
||
|
|
- ISO enums: `MMEDirections`, `MMEFilterClasses`, `MMEFineLocations1/2/3`, `MMETransducerMainLocation`, `MMEPhysicalDimensions`, `MMEPositions`, `MMETestObjects`
|
||
|
|
- `ISO13499FileDb.IsoDb` (static singleton with methods like `GetDirectionByIso`, `GetFilterClassByIso`, etc.)
|
||
|
|
- `ISO.IsoCode.GetString(...)` (static method for code generation)
|
||
|
|
- `Common.BindableBase` (commented out in `Zone` class definition; not used)
|
||
|
|
|
||
|
|
### Inferred Consumers:
|
||
|
|
- UI layers (WPF) that use `RegionAdorner` to draw/edit regions on images.
|
||
|
|
- Serialization/deserialization logic (via `ToISORegion` and `Region(TemplateRegion)` constructor).
|
||
|
|
- Code that accesses `Zone.Regions` and `Region.RegionChannels` for analysis or export.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 5. Gotchas
|
||
|
|
|
||
|
|
- **`PictureIndex` and `AllPictures`**:
|
||
|
|
`AllPictures` is lazily initialized on first access and sorted by `FileInfo.FullName`. If the `"ZonePictures"` directory is missing or inaccessible, `_fileNames` remains `null`, and `PictureIndex` will always be `-1`.
|
||
|
|
|
||
|
|
- **Scaling in `GetUpperLeft()`/`GetLowerRight()`**:
|
||
|
|
The scaling logic assumes the `AdornedElement` is an `Image` with a `Source` whose dimensions differ from `RenderSize`. If `Source` is `null`, `GetLowerRight()` returns `(0,0)`; `GetUpperLeft()` may throw if `Source` is `null` (though not explicitly guarded).
|
||
|
|
|
||
|
|
- **Null Handling in ISO Enums**:
|
||
|
|
Enum properties (e.g., `RegionDirection`) may be `null`, and their string representations use `"?"` (or `"??"`, `"????"`). This is critical for ISO code generation.
|
||
|
|
|
||
|
|
- **Channel Filtering**:
|
||
|
|
`FilterRegionChannels()` mutates `_regionChannels`/`_regionUIChannels` in-place. If `RegionChannels` is set externally, `DetermineAvailableISOSettings()` is triggered, which may overwrite user selections if no channels match.
|
||
|
|
|
||
|
|
- **`FileInfoComparer`**:
|
||
|
|
Compares by `FullName`, not `Name`. This may cause unexpected ordering if paths differ (e.g., `"ZonePictures/a.png"` vs `"ZonePictures/sub/a.png"`).
|
||
|
|
|
||
|
|
- **No `INotifyPropertyChanged`**:
|
||
|
|
The `Zone` class has `Common.BindableBase` commented out. Changes to properties (e.g., `PictureIndex`, `Regions`) do not raise change notifications (unless handled elsewhere).
|
||
|
|
|
||
|
|
- **`IsNew` Side Effects**:
|
||
|
|
Setting `IsNew = true` hides delete controls and shows add controls, but does *not* reset `SelectRect` or `MyRegion` coordinates.
|
||
|
|
|
||
|
|
- **`ToISORegion` Coordinate Conversion**:
|
||
|
|
Converts `Point` (WPF, `double`) to `System.Drawing.Point` (WinForms, `int`) via `Convert.ToInt32(...)`, which truncates (not rounds). May cause precision loss.
|
||
|
|
|
||
|
|
- **No Thread Safety**:
|
||
|
|
`AllPictures` uses non-thread-safe lazy initialization (`_fileNames`). Concurrent access may cause race conditions.
|
||
|
|
|
||
|
|
- **`_pictureIndex` Field**:
|
||
|
|
`_pictureIndex` is private and used only in `PictureIndex`. It is not synchronized with `PictureSource` if set directly (though the property setter handles this).
|
||
|
|
|
||
|
|
- **`RegionAdorner` Mouse Capture**:
|
||
|
|
`EndSelection` calls `ReleaseMouseCapture()`, but there is no explicit `CaptureMouse()` call in `DrawSelection`/`MoveSelection`. Mouse events may fire even after drag ends if capture was not held.
|
||
|
|
|
||
|
|
- **Hardcoded Paths**:
|
||
|
|
`"ZonePictures"` is hardcoded as the picture directory. No configuration or fallback is provided.
|
||
|
|
|
||
|
|
- **`TemplateRegion` Constructor**:
|
||
|
|
`ToISORegion` passes `template.IsLocalOnly` to `TemplateRegion` constructor, but `IsLocalOnly` is not used elsewhere in the provided code.
|
||
|
|
|
||
|
|
- **`Region` Constructor Overload**:
|
||
|
|
The `Region(TestObjectTemplate, TemplateRegion)` constructor does *not* call `FilterRegionChannels()` until after setting all properties, but `SetISOCode()` is called at the end. This is safe, but the intermediate state may be inconsistent.
|
||
|
|
|
||
|
|
- **`AllX` Properties**:
|
||
|
|
Setting `AllX` (e.g., `AllDirections`) populates `AllXStrings` from `Text_L1`, but setting `AllXStrings` does *not* update `AllX`. This breaks two-way binding if used.
|
||
|
|
|
||
|
|
- **`RegionAdorner` Mouse Events**:
|
||
|
|
`Region_MouseLeftButtonDown` raises `OnRegionSelected`, but does *not* set `AnchorPoint` or begin selection. This must be handled externally (e.g., by the adorner layer).
|
||
|
|
|
||
|
|
- **`RegionAdorner` `_MeasuredSize`**:
|
||
|
|
`_MeasuredSize` is set from `adornedElement.RenderSize` in the constructor. If the element resizes later, scaling calculations become incorrect.
|
||
|
|
|
||
|
|
- **`RegionAdorner` `IsNew` Default**:
|
||
|
|
`IsNew` defaults to `true`, meaning the adorner starts in "drawing" mode unless explicitly set to `false`.
|
||
|
|
|
||
|
|
- **`RegionAdorner` `AnchorPoint` Initialization**:
|
||
|
|
`AnchorPoint` is not initialized in the constructor. If `DrawSelection` is called before `AnchorPoint` is set, it will be `
|