Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 37 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,22 @@ The framework depends on [RMC.Numerics](https://github.com/USACE-RMC/Numerics) t

### Prerequisites

- [.NET 10.0 SDK](https://dotnet.microsoft.com/download)
- Visual Studio 2022 (17.12 or later)
- [.NET 10.0 SDK](https://dotnet.microsoft.com/download/dotnet/10.0)
- Optional IDE: Visual Studio 2026 (18.0 or later), which [supports targeting .NET 10](https://learn.microsoft.com/en-us/dotnet/core/porting/versioning-sdk-msbuild-vs#targeting-and-support-rules)
- Windows 10 or later

### Build and Test

Run these commands from the repository root:

```bash
dotnet build WPF-Framework.sln
dotnet test WPF-Framework.sln
```

### Build Packages

```bash
```powershell
.\scripts\pack-wpf-framework.ps1 -Configuration Release -Version 1.0.5
```

Expand All @@ -63,23 +65,35 @@ This creates and validates the following NuGet packages in `artifacts/packages/`
| [`RMC.Wpf.Framework.Support`](https://www.nuget.org/packages/RMC.Wpf.Framework.Support/) | SoftwareUpdate and updater content files | None |
| [`RMC.Wpf.Framework.Controls`](https://www.nuget.org/packages/RMC.Wpf.Framework.Controls/) | FrameworkUI, control libraries, AvalonDock fork | Core, Models, Support, RMC.Numerics 2.1.4+ |

### Minimal Application
### Application Startup

```csharp
// In App.xaml.cs — initialize theme before creating any UI
FrameworkUI.ThemeManager.SetTheme(FrameworkUI.ThemeColor.Light);
The shell requires an application-specific `FrameworkInterfaces.IProject` implementation and a concrete subclass of `FrameworkUI.FrameworkUIController`. The controller provides the project tree, menus, and document/property views; it is the value assigned to `MainWindow.ProjectNode`.

Use this helper from your WPF application's `OnStartup` override or `Startup` handler, on the UI thread. Omit `StartupUri` in `App.xaml` so WPF does not create a second window. Supply a factory that creates your controller around an initialized project. The factory runs after theme initialization because controllers can construct WPF controls.

// Create project and controller
var project = new MyProject();
var controller = new MyProjectController(project);
```csharp
public static class ShellStartup
{
public static FrameworkUI.MainWindow Show(
System.Func<FrameworkUI.FrameworkUIController> createProjectNode)
{
FrameworkUI.ThemeManager.SetTheme(FrameworkUI.ThemeColor.Light);
FrameworkUI.FrameworkUIController projectNode = createProjectNode();

// Show the main window
var mainWindow = new FrameworkUI.MainWindow();
mainWindow.ProjectNode = controller;
mainWindow.Show();
var mainWindow = new FrameworkUI.MainWindow
{
ProjectNode = projectNode
};
System.Windows.Application.Current.MainWindow = mainWindow;
mainWindow.Show();
return mainWindow;
}
}
```

Run `FrameworkUI.Demo` for a complete working example.
`Application.Current` and the application's resource dictionaries must already exist. Merge the icon and control dictionaries used by your views into `App.xaml`; see the working [demo resources](src/FrameworkUI.Demo/App.xaml). `MainWindow` restores the saved theme preference when it loads user settings, so that preference can override the initial Light theme.

Run `FrameworkUI.Demo` for a complete application. Its [startup handler](src/FrameworkUI.Demo/App.xaml.cs), [project model](src/FrameworkUI.Demo/Model/DemoProject.cs), and [project controller](src/FrameworkUI.Demo/UI/DemoProjectNode.cs) show the host implementations and initialization order.

## Documentation

Expand All @@ -104,17 +118,21 @@ Comprehensive documentation is available in the [docs/](docs/index.md) folder:

### Theme Switching

Three built-in themes with runtime switching — all controls update automatically via `DynamicResource` bindings:
Three built-in themes support runtime switching through `DynamicResource` bindings. Call this on the UI thread of a running WPF application (for example, in a theme-menu handler):

```csharp
FrameworkUI.ThemeManager.SetTheme(FrameworkUI.ThemeColor.Dark);
```

This changes the active theme. It does not save a preference; the shell's Options dialog manages persisted theme settings.

### Undo/Redo

Built-in undo/redo for element properties with automatic change tracking:
Add the following field and property inside your concrete `FrameworkInterfaces.ElementBase` subclass, alongside its required constructor, metadata, and persistence members. `RecordPropertyChange` is a protected base-class method: it records the edit, raises `PropertyChanged`, and marks the element dirty when undo recording is enabled. No additional notification call is needed.

```csharp
private string _customValue = string.Empty;

public string CustomValue
{
get => _customValue;
Expand All @@ -130,6 +148,8 @@ public string CustomValue
}
```

Use the element's `UndoManager.Undo()` and `UndoManager.Redo()` to replay edits. Set `IsUndoEnabled` to `false` while loading data or applying untracked changes, then restore its previous value.

### Docking Layout

VS2013-style docking with tabbed documents, auto-hide panels, and floating windows powered by a vendored AvalonDock fork.
Expand Down
42 changes: 36 additions & 6 deletions docs/assets/gallery/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Gallery Screenshot Checklist

Save screenshots in this folder using the filenames below. Blue theme is the default capture style.
These screenshots support [the public control gallery](../../gallery.md). Capture the running demo applications in `src/` and keep filenames, theme labels, and captions consistent with the images.

## FrameworkUI

Expand All @@ -9,13 +9,21 @@ Save screenshots in this folder using the filenames below. Blue theme is the def
- `frameworkui-shell-dark.png`
- `frameworkui-hazard-document-blue.png`

Launch `FrameworkUI.Demo`. The demo creates a blank temporary project on startup. Use **Project > New Hazard Element...**, or right-click **Hazard Functions** and choose **New Hazard Element...**, to add a named sample hazard. Double-click the new element to open its document. Use the demo's distribution and property controls to display a meaningful example.

Choose the theme under **Tools > Options > Application**. Keep the same window size, docking layout, selected document, and data for the Blue, Light, and Dark shell captures. Capture the hazard document in Blue with its chart and properties visible; its tabular results and parameter sets are separate tabs.

The captured **Example Hazard** uses Log-Pearson Type III with mean (log) `3`, standard deviation (log) `0.5`, skew (log) `0`, effective record length `100`, and uncertainty enabled. These settings form an illustrative demo example.

## GenericControls

- `generic-input-controls-blue.png`
- `generic-date-time-color-blue.png`
- `generic-property-editors-light.png`
- `generic-datagrid-blue.png`

Launch `GenericControls.Demo` and select the matching control groups. Use Blue for the input, date/time/color, and data grid images. Use Light for the property editor image. Keep representative controls and values visible without clipping.

## NumericControls

- `numeric-distribution-selector-blue.png`
Expand All @@ -27,27 +35,49 @@ Save screenshots in this folder using the filenames below. Blue theme is the def
- `numeric-bin-definitions-blue.png`
- `numeric-bivariate-cdf-blue.png`

Launch `NumericControls.Demo`, select Blue, and visit each corresponding tab. Use the sample values initialized by the demo except for the uncertainty example described below. Ensure tables, distribution parameters, and plots have finished rendering before capture.

The uncertain curve and uncertain table captures share six illustrative Normal distributions entered through the demo UI: X values `[0, 2, 4, 6, 8, 10]`, means `[30, 24, 19, 15, 12, 10]`, and standard deviation `1` for every row. These are demonstration values, not measured data.

On **Time Series**, select the built-in **Hourly** example: constant value `15`, beginning `1980-07-30`. The pictured data comes from the local Hourly example. The separate USGS option retrieves external data. On **Bivariate CDF**, select the **Plot** tab.

## OxyPlotControls

- `oxyplot-toolbar-blue.png`
- `oxyplot-properties-blue.png`
- `oxyplot-series-selector-blue.png`

Launch `OxyPlotControls.Demo` and select Blue. Select **Heat Map Series** for the toolbar capture. Use **Line Series** with **General Plot Settings** visible for the properties capture. Open the **Series Type** list for the selector capture, keeping the line-series example visible behind it.

## DatabaseControls

- `database-table-viewer-blue.png`

Launch `DatabaseControls.Demo`, select Blue, and load the [synthetic sample CSV](samples/synthetic-gallery-sample.csv). The capture uses 12 fictional records with **Sample ID**, **Category**, **Value**, **Units**, and **Source** columns. Each row is labeled **Synthetic** and uses **example units**. These records demonstrate the table controls and are not observed measurements or production data. The demo starts without a loaded table.

## ExpressionParserControls

- `expression-calculator-blue.png`
- `expression-calculator-light.png`

Launch `ExpressionParserControls.Demo`. This demo initializes Light and has no theme selector. Enter `((120 + 80) / 2) ^ 2` so the editor, operator controls, and evaluated result `10000` are visible. This standalone demo does not host the optional function browser.

## DAGControls

- `dag-flowgraph-canvas-blue.png`
- `dag-flowgraph-canvas.png`

Launch `DAG.Demo` and retain its default appearance; it does not expose the framework theme selector. The canvas starts empty. Add sample nodes from the toolbar or canvas context menu and arrange them with room for their labels and input/output connectors. Capture the actual populated canvas.

The demo's **Save** and **Load** handlers are placeholders and cannot save or open graph files. Connection creation is intended to use a drag from an output circle to an input circle, but this workflow was not verified for the gallery capture. The screenshot and caption therefore describe the visible nodes and connectors without claiming a successful connection.

## Capture Notes

- Capture from the demo apps in `src/`.
- Keep screenshots focused on the relevant control.
- Prefer 1200-1600 px wide PNGs.
The 18 new screenshots were captured on **2026-10-07** from Release demo builds at commit `05acb1e`. The four preexisting GenericControls images were retained. The new screenshots retain their native pixel resolution, with focused regions cropped from JPEG captures and saved as PNG.

- Capture actual demo windows or focused control regions, with text readable at the gallery's displayed size.
- Prefer 1200–1600 px wide PNGs for full windows when the display permits. Keep focused controls at their native resolution; do not upscale smaller captures.
- Use the demos' bundled or initialized sample inputs where available. The database table is an explicitly synthetic gallery example.
- Keep window dimensions and framing consistent within each group, especially the shell theme comparison.
- Wait for layout and rendering to settle. Move the pointer away from the focal content and dismiss transient tooltips or unrelated dialogs.
- Avoid local paths, personal data, debug windows, and unrelated desktop content.
- Inspect every image for cropped labels, blank plots, selection artifacts, and unintended horizontal scrolling.
- Verify that every image referenced by `docs/gallery.md` exists and that its theme matches its filename and alternative text.
Binary file added docs/assets/gallery/dag-flowgraph-canvas.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/gallery/frameworkui-shell-blue.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/gallery/frameworkui-shell-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/gallery/frameworkui-shell-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/gallery/numeric-time-series-blue.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/gallery/oxyplot-properties-blue.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/gallery/oxyplot-toolbar-blue.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions docs/assets/gallery/samples/synthetic-gallery-sample.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Sample ID,Category,Value,Units,Source
DEMO-001,Group A,12.5,example units,Synthetic
DEMO-002,Group A,18,example units,Synthetic
DEMO-003,Group A,23.5,example units,Synthetic
DEMO-004,Group A,31,example units,Synthetic
DEMO-005,Group B,15,example units,Synthetic
DEMO-006,Group B,21.5,example units,Synthetic
DEMO-007,Group B,28,example units,Synthetic
DEMO-008,Group B,36.5,example units,Synthetic
DEMO-009,Group C,10,example units,Synthetic
DEMO-010,Group C,17.5,example units,Synthetic
DEMO-011,Group C,26,example units,Synthetic
DEMO-012,Group C,34.5,example units,Synthetic
32 changes: 16 additions & 16 deletions docs/gallery.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Control Gallery

This gallery outlines the screenshots used to show the visible controls in the WPF Framework demo applications. Blue theme is the default capture style. Light and Dark screenshots are included only where they show theme coverage.
Explore the application shell, editors, plotting tools, and graph controls in the WPF Framework demo applications. Each screenshot shows a running demo with its sample data or a small synthetic example.

Screenshots belong in `docs/assets/gallery/` using the filenames shown below.
Most controls are shown in the Blue theme. The shell comparison also shows Light and Dark; property editors and the expression calculator use Light, and the flow graph uses its demo's default appearance.

## Contents

Expand Down Expand Up @@ -63,7 +63,7 @@ See: [Themes](themes.md)

![FrameworkUI hazard document in blue theme](assets/gallery/frameworkui-hazard-document-blue.png)

Document view with an OxyPlot chart, vertical plot toolbar, tabular results, and properties workflow.
Hazard document with an OxyPlot chart, vertical plot toolbar, and editable properties. Separate document tabs provide tabular results and parameter sets.

See: [OxyPlot Controls](oxyplot-controls.md), [Generic Controls](generic-controls.md)

Expand All @@ -89,7 +89,7 @@ See: [Generic Controls](generic-controls.md)

### Property Editors

![Generic property editors in blue theme](assets/gallery/generic-property-editors-light.png)
![Generic property editors in light theme](assets/gallery/generic-property-editors-light.png)

Property editors for text, numbers, booleans, fonts, colors, lines, alignment, points, dates, and custom content.

Expand All @@ -112,23 +112,23 @@ Demo source: `src/NumericControls.Demo/`

![Numeric distribution selector in blue theme](assets/gallery/numeric-distribution-selector-blue.png)

Distribution selector with fitting options, parameters, plot, and statistics.
Normal distribution selector with parameters, a density plot and sample histogram, and summary statistics.

See: [Numeric Controls](numeric-controls.md)

### Uncertain Curve Editor

![Numeric uncertain curve editor in blue theme](assets/gallery/numeric-uncertain-curve-editor-blue.png)

Curve editor for ordered data with uncertainty.
Curve editor for ordered data with uncertainty. This illustrative example uses Normal distributions at six ordinates, with a standard deviation of 1 at each ordinate.

See: [Numeric Controls](numeric-controls.md)

### Uncertain Table Editor

![Numeric uncertain table editor in blue theme](assets/gallery/numeric-uncertain-table-editor-blue.png)

Table editor for uncertain ordered data.
Table editor showing the same six illustrative Normal distributions as the uncertain curve example.

See: [Numeric Controls](numeric-controls.md)

Expand All @@ -152,7 +152,7 @@ See: [Numeric Controls](numeric-controls.md)

![Numeric time series table in blue theme](assets/gallery/numeric-time-series-blue.png)

Time series table with selectable sample data sets.
Time series table showing the demo's built-in hourly example, with a constant value of 15 beginning July 30, 1980.

See: [Numeric Controls](numeric-controls.md)

Expand All @@ -168,7 +168,7 @@ See: [Numeric Controls](numeric-controls.md)

![Numeric bivariate CDF in blue theme](assets/gallery/numeric-bivariate-cdf-blue.png)

Bivariate empirical CDF control.
Bivariate empirical CDF control with its Plot tab selected.

See: [Numeric Controls](numeric-controls.md)

Expand All @@ -180,15 +180,15 @@ Demo source: `src/OxyPlotControls.Demo/`

![OxyPlot toolbar in blue theme](assets/gallery/oxyplot-toolbar-blue.png)

Plot view with vertical toolbar for pan, zoom, annotation, export, and properties.
Heat map example with a vertical toolbar for pan, zoom, annotation, export, and properties.

See: [OxyPlot Controls](oxyplot-controls.md)

### Plot Properties

![OxyPlot properties in blue theme](assets/gallery/oxyplot-properties-blue.png)

Properties panel for axes, series, annotations, legends, and layout settings.
Line-series example beside the properties panel, showing plot title, typography, plot area, and background settings.

See: [OxyPlot Controls](oxyplot-controls.md)

Expand All @@ -208,7 +208,7 @@ Demo source: `src/DatabaseControls.Demo/`

![Database table viewer in blue theme](assets/gallery/database-table-viewer-blue.png)

Table viewer with file/table selection, editable cells, row/column/cell selection, autofit columns, and field calculator access.
Table viewer displaying the [synthetic sample CSV](assets/gallery/samples/synthetic-gallery-sample.csv), with file/table selection, editable cells, row/column/cell selection, autofit columns, and field calculator access.

See: [Database Controls](database-controls.md)

Expand All @@ -218,9 +218,9 @@ Demo source: `src/ExpressionParserControls.Demo/`

### Calculator Control

![Expression calculator in blue theme](assets/gallery/expression-calculator-blue.png)
![Expression calculator in light theme](assets/gallery/expression-calculator-light.png)

Calculator control with expression editor, operator buttons, function browser, expression builder, and result output.
Calculator control with an expression editor, operator buttons, case sensitivity option, and evaluated result output.

See: [Database Controls](database-controls.md)

Expand All @@ -230,8 +230,8 @@ Demo source: `src/DAG.Demo/`

### Flow Graph Canvas

![DAG flow graph canvas in blue theme](assets/gallery/dag-flowgraph-canvas-blue.png)
![DAG flow graph canvas with sample nodes and input and output connectors](assets/gallery/dag-flowgraph-canvas.png)

Flow graph canvas with nodes, connectors, add-node workflow, and connection feedback.
Flow graph canvas with sample nodes and their input and output connectors. The demo supports adding nodes from the canvas context menu and arranging them on the grid.

See: [DAG Controls](dag-controls.md)
Loading