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
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ cff-version: 1.2.0
message: "If you use this software, please cite it as below."
type: software
title: "WPF Framework"
version: "1.0.3"
date-released: "2026-07-14"
version: "1.0.4"
date-released: "2026-07-17"
license: 0BSD
repository-code: "https://github.com/USACE-RMC/WPF-Framework"
url: "https://github.com/USACE-RMC/WPF-Framework"
Expand Down
6 changes: 3 additions & 3 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
<PackageProjectUrl>https://github.com/USACE-RMC/WPF-Framework</PackageProjectUrl>
<RepositoryUrl>https://github.com/USACE-RMC/WPF-Framework</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<Version>1.0.3</Version>
<AssemblyVersion>1.0.3.0</AssemblyVersion>
<FileVersion>1.0.3.0</FileVersion>
<Version>1.0.4</Version>
<AssemblyVersion>1.0.4.0</AssemblyVersion>
<FileVersion>1.0.4.0</FileVersion>

<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<IsPackable>false</IsPackable>
Expand Down
6 changes: 3 additions & 3 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
<NSubstituteVersion>4.2.1</NSubstituteVersion>
<NUnitVersion>3.14.0</NUnitVersion>
<NUnit3TestAdapterVersion>4.5.0</NUnit3TestAdapterVersion>
<!-- Restore the latest compatible RMC.Numerics 2.x release for source builds. -->
<RmcNumericsVersion>2.*</RmcNumericsVersion>
<!-- Restore the released RMC.Numerics package used for WPF Framework validation. -->
<RmcNumericsVersion>2.1.4</RmcNumericsVersion>
<!-- NuGet package dependencies require a valid version range, not a floating wildcard. -->
<RmcNumericsPackageDependencyVersion>[2.1.1,3.0.0)</RmcNumericsPackageDependencyVersion>
<RmcNumericsPackageDependencyVersion>[2.1.4,3.0.0)</RmcNumericsPackageDependencyVersion>
<SourceGearSqlite3Version>3.50.4.5</SourceGearSqlite3Version>
<SystemDataSQLiteVersion>2.0.2</SystemDataSQLiteVersion>
<XunitVersion>2.9.2</XunitVersion>
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ WPF Framework is a free and open-source .NET 10.0 application framework for buil

WPF Framework can be consumed from source project references or packaged into NuGet bundles with `scripts/pack-wpf-framework.ps1`. The package layout follows the internal dependency map: Core, Models, Support, then Controls.

The framework depends on [RMC.Numerics](https://github.com/USACE-RMC/Numerics) through central NuGet package management in `Directory.Packages.props`. Source builds restore the latest compatible 2.x package; NuGet bundles declare compatibility with RMC.Numerics 2.1.1 or later, below 3.0.0.
The framework depends on [RMC.Numerics](https://github.com/USACE-RMC/Numerics) through central NuGet package management in `Directory.Packages.props`. Source builds restore RMC.Numerics 2.1.4; NuGet bundles declare compatibility with RMC.Numerics 2.1.4 or later, below 3.0.0.

## Solution Structure

Expand Down Expand Up @@ -51,7 +51,7 @@ dotnet test WPF-Framework.sln
### Build Packages

```bash
.\scripts\pack-wpf-framework.ps1 -Configuration Release -Version 1.0.3
.\scripts\pack-wpf-framework.ps1 -Configuration Release -Version 1.0.4
```

This creates and validates the following NuGet packages in `artifacts/packages/`:
Expand All @@ -61,7 +61,7 @@ This creates and validates the following NuGet packages in `artifacts/packages/`
| [`RMC.Wpf.Framework.Core`](https://www.nuget.org/packages/RMC.Wpf.Framework.Core/) | FrameworkInterfaces, Themes | None |
| [`RMC.Wpf.Framework.Models`](https://www.nuget.org/packages/RMC.Wpf.Framework.Models/) | DAG, DatabaseManager, ExpressionParser, OxyPlot libraries | ClosedXML, DocumentFormat.OpenXml, ExcelNumberFormat, FastMember, SourceGear.sqlite3, System.Data.SQLite |
| [`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.x |
| [`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

Expand Down
4 changes: 2 additions & 2 deletions codemeta.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
"@type": "SoftwareSourceCode",
"name": "WPF Framework",
"description": "A free and open-source .NET 10 application framework for building Windows desktop project management applications. Provides a docking application shell with theming, project explorer, undo/redo, and specialized controls for charting, numeric input, databases, expression parsing, and directed acyclic graphs.",
"version": "1.0.3",
"version": "1.0.4",
"dateCreated": "2025-12-29",
"dateModified": "2026-07-14",
"dateModified": "2026-07-17",
"license": "https://spdx.org/licenses/0BSD",
"codeRepository": "https://github.com/USACE-RMC/WPF-Framework",
"issueTracker": "https://github.com/USACE-RMC/WPF-Framework/issues",
Expand Down
6 changes: 3 additions & 3 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ The packaging projects in `src/Packaging/` create four bundles. Packages should
| `RMC.Wpf.Framework.Core` | FrameworkInterfaces, Themes | None |
| `RMC.Wpf.Framework.Models` | DAG, DatabaseManager, ExpressionParser, OxyPlot, OxyPlot.Wpf, OxyPlot.Wpf.Shared | ClosedXML, DocumentFormat.OpenXml, ExcelNumberFormat, FastMember, SourceGear.sqlite3, System.Data.SQLite |
| `RMC.Wpf.Framework.Support` | SoftwareUpdate plus SoftwareUpdate.Updater content files | None |
| `RMC.Wpf.Framework.Controls` | FrameworkUI, GenericControls, NumericControls, OxyPlotControls, DatabaseControls, ExpressionParserControls, DAGControls, Xceed.Wpf.AvalonDock, Xceed.Wpf.AvalonDock.Themes.VS2013 | `RMC.Wpf.Framework.Core`, `RMC.Wpf.Framework.Models`, `RMC.Wpf.Framework.Support`, `RMC.Numerics` 2.x |
| `RMC.Wpf.Framework.Controls` | FrameworkUI, GenericControls, NumericControls, OxyPlotControls, DatabaseControls, ExpressionParserControls, DAGControls, Xceed.Wpf.AvalonDock, Xceed.Wpf.AvalonDock.Themes.VS2013 | `RMC.Wpf.Framework.Core`, `RMC.Wpf.Framework.Models`, `RMC.Wpf.Framework.Support`, `RMC.Numerics` 2.1.4+ |

AvalonDock is a vendored UI dependency and is packaged with `RMC.Wpf.Framework.Controls`, not Core. `RMC.Numerics` is consumed as a NuGet package through central package management and should not be referenced through local `HintPath` DLLs. Source builds use the floating `2.*` version, while packages declare a compatible `[2.1.1,3.0.0)` dependency range.
AvalonDock is a vendored UI dependency and is packaged with `RMC.Wpf.Framework.Controls`, not Core. `RMC.Numerics` is consumed as a NuGet package through central package management and should not be referenced through local `HintPath` DLLs. Source builds restore `RMC.Numerics` 2.1.4, while packages declare a compatible `[2.1.4,3.0.0)` dependency range.

## 3. Core Framework

Expand Down Expand Up @@ -217,7 +217,7 @@ Key additions beyond upstream:

| Dependency | Source | Purpose |
|-----------|--------|---------|
| **RMC.Numerics** | [USACE-RMC/Numerics](https://github.com/USACE-RMC/Numerics) NuGet package, latest compatible 2.x | Statistical distributions, parameter estimation, bootstrap analysis. Required by NumericControls and DatabaseControls. |
| **RMC.Numerics** | [USACE-RMC/Numerics](https://github.com/USACE-RMC/Numerics) NuGet package, 2.1.4 or later compatible 2.x | Statistical distributions, parameter estimation, bootstrap analysis. Required by NumericControls and DatabaseControls. |

All other dependencies are either vendored into the solution (AvalonDock, OxyPlot) or available as NuGet packages (System.Data.SQLite, DocumentFormat.OpenXml, etc.).

Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ For NuGet consumption, reference the Controls bundle. It brings in Core, Models,

```xml
<ItemGroup>
<PackageReference Include="RMC.Wpf.Framework.Controls" Version="1.0.3" />
<PackageReference Include="RMC.Wpf.Framework.Controls" Version="1.0.4" />
</ItemGroup>
```

Expand Down
31 changes: 27 additions & 4 deletions scripts/pack-wpf-framework.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,16 @@ $expectedVersionedEntries = @{
}

$expectedReleaseNotes = @{
"RMC.Wpf.Framework.Core" = "Coordinated WPF Framework 1.0.3 release; no package-specific functional changes."
"RMC.Wpf.Framework.Models" = "Coordinated WPF Framework 1.0.3 release; no package-specific functional changes."
"RMC.Wpf.Framework.Support" = "Coordinated WPF Framework 1.0.3 release; no package-specific functional changes."
"RMC.Wpf.Framework.Controls" = "Version 1.0.3 defaults the DatabaseControls TableViewer Export Table dialog to CSV while retaining DBF, Excel, and SQLite options."
"RMC.Wpf.Framework.Core" = "Coordinated WPF Framework 1.0.4 release; no package-specific functional changes."
"RMC.Wpf.Framework.Models" = "Coordinated WPF Framework 1.0.4 release; no package-specific functional changes."
"RMC.Wpf.Framework.Support" = "Coordinated WPF Framework 1.0.4 release; no package-specific functional changes."
"RMC.Wpf.Framework.Controls" = "Version 1.0.4 updates RMC.Numerics to 2.1.4 and improves NumericControls validation and distribution selector compatibility."
}

$expectedPackageDependencies = @{
"RMC.Wpf.Framework.Controls" = @{
"RMC.Numerics" = "[2.1.4,3.0.0)"
}
}

foreach ($packageId in $expectedEntries.Keys) {
Expand Down Expand Up @@ -156,6 +162,23 @@ foreach ($packageId in $expectedEntries.Keys) {
throw "$($package.Name) has unexpected NuGet release notes."
}

if ($expectedPackageDependencies.ContainsKey($packageId)) {
foreach ($dependencyId in $expectedPackageDependencies[$packageId].Keys) {
$dependency = $nuspec.SelectSingleNode("/n:package/n:metadata/n:dependencies/n:group/n:dependency[@id='$dependencyId']", $namespaceManager)
if ($dependency -eq $null) {
throw "$($package.Name) is missing NuGet dependency $dependencyId."
}

$dependencyVersion = $dependency.Attributes["version"].Value
$expectedDependencyVersion = $expectedPackageDependencies[$packageId][$dependencyId]
$normalizedDependencyVersion = $dependencyVersion.Replace(" ", "")
$normalizedExpectedDependencyVersion = $expectedDependencyVersion.Replace(" ", "")
if ($normalizedDependencyVersion -ne $normalizedExpectedDependencyVersion) {
throw "$($package.Name) declares $dependencyId dependency $dependencyVersion instead of $expectedDependencyVersion."
}
}
}

$numericVersion = ($packageVersion -split '-')[0]
$expectedBinaryVersion = "$numericVersion.0"
$inspectionDirectory = Join-Path ([System.IO.Path]::GetTempPath()) "wpf-framework-package-$([Guid]::NewGuid().ToString('N'))"
Expand Down
6 changes: 3 additions & 3 deletions src/DAGControls/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Reflection;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
Expand Down Expand Up @@ -50,5 +50,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.3.0")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyVersion("1.0.4.0")]
[assembly: AssemblyFileVersion("1.0.4.0")]
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,13 @@ public DistributionDataItem(UncertainOrderedPairedData d, UnivariateDistribution
_isStrictY = strictY;
_xOrder = orderX;
_yOrder = orderY;
DistributionName = UnivariateDistributionFactory.CreateDistribution(Distribution).DisplayName;
if (_data is not null && _data.Count > 0)
DistributionName = _data[0].Y.DisplayName;
else if (UnivariateDistributionFactory.TryCreateDistribution(Distribution, out var distribution) &&
distribution is not null)
DistributionName = distribution.DisplayName;
else
DistributionName = Distribution.ToString();
Refresh();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,6 @@ private static void DistributionOptionsCallback(DependencyObject d, DependencyPr
{
UncertainOrderedDataSelectorControl thisControl = (UncertainOrderedDataSelectorControl)d;
thisControl.Distributions.Clear();
UnivariateDistributionBase distribution;
if ((e.NewValue == null) || (e.NewValue.GetType() != typeof(List<UnivariateDistributionType>)))
{
thisControl.DistributionOptions = DefaultDistributionOptions;
Expand All @@ -443,8 +442,8 @@ private static void DistributionOptionsCallback(DependencyObject d, DependencyPr
{
foreach (var dist in (List<UnivariateDistributionType>)e.NewValue)
{
distribution = UnivariateDistributionFactory.CreateDistribution(dist);
if (distribution == null) continue;
if (!UnivariateDistributionFactory.TryCreateDistribution(dist, out var distribution) ||
distribution is null) continue;
//
var ordinates = new List<UncertainOrdinate>();
for (int i = 0; i <= 5; i++)
Expand All @@ -459,9 +458,9 @@ private static void DistributionOptionsCallback(DependencyObject d, DependencyPr
}

/// <summary>
/// Currently does not support bivariate, univariate, or kernel density.
/// Returns the default distribution types supported by the uncertain curve selector.
/// </summary>
/// <returns></returns>
/// <returns>A list of supported distribution types.</returns>
public static List<UnivariateDistributionType> DefaultDistributionOptions
{
get
Expand All @@ -480,6 +479,7 @@ public static List<UnivariateDistributionType> DefaultDistributionOptions
(o != UnivariateDistributionType.KernelDensity) &&
(o != UnivariateDistributionType.Mixture) &&
(o != UnivariateDistributionType.NoncentralT) &&
(o != UnivariateDistributionType.UserDefined) &&
(o != UnivariateDistributionType.UniformDiscrete) &&
(o != UnivariateDistributionType.Poisson)).ToList();
}
Expand Down Expand Up @@ -698,8 +698,13 @@ private void ValidationGrid_PreviewAddRows(int startRowIndex, int nRows, ref boo
//
DistributionDataItem selectedItem = (DistributionDataItem)CurveUncertaintyComboBox.SelectedItem;
var type = selectedItem.Data.Distribution;
UnivariateDistributionBase distribution;
if (selectedItem.Data.Count > 0)
distribution = selectedItem.Data[0].Y.Clone();
else if (!UnivariateDistributionFactory.TryCreateDistribution(type, out distribution) || distribution is null)
return;
for (int i = startRowIndex; i < startRowIndex + nRows; i++)
selectedItem.Data.Insert(i, new UncertainOrdinate(0d, UnivariateDistributionFactory.CreateDistribution(type)));
selectedItem.Data.Insert(i, new UncertainOrdinate(0d, distribution.Clone()));
// Refresh the view
selectedItem.Refresh(); // MinimumX, MaximumX, MinimumY, MaximumY, IsStrictX, IsStrictY, OrderX, OrderY)
ValidationGrid.Items.Refresh();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,6 @@ public IList<UnivariateDistributionType> DistributionOptions
private static void DistributionOptionsCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
UncertainOrderedDataTableEditor thisControl = (UncertainOrderedDataTableEditor)d;
UnivariateDistributionBase distribution;
IList<UnivariateDistributionType> distOptions = e.NewValue as IList<UnivariateDistributionType>;
if (e.NewValue == null || distOptions == null)
{
Expand All @@ -397,21 +396,21 @@ private static void DistributionOptionsCallback(DependencyObject d, DependencyPr
foreach (var dist in distOptions)
{
if (thisControl._distributions.Any(o => o.Distribution == dist)) continue;
distribution = UnivariateDistributionFactory.CreateDistribution(dist);
if (distribution == null) continue;
if (!UnivariateDistributionFactory.TryCreateDistribution(dist, out var distribution) ||
distribution is null) continue;
var ordinates = new List<UncertainOrdinate>();
for (int i = 0; i <= 1; i++)
ordinates.Add(new UncertainOrdinate(i, UnivariateDistributionFactory.CreateDistribution(dist)));
ordinates.Add(new UncertainOrdinate(i, distribution.Clone()));
var uncertainData = new UncertainOrderedPairedData(ordinates, thisControl.IsStrictX, thisControl.OrderX, thisControl.IsStrictY, thisControl.OrderY, dist);
thisControl._distributions.Add(uncertainData);
}
}
}

/// <summary>
/// Currently does not support bivariate, empirical, or kernel density.
/// Returns the default distribution types supported by the uncertain curve table editor.
/// </summary>
/// <returns></returns>
/// <returns>A list of supported distribution types.</returns>
public static List<UnivariateDistributionType> DefaultDistributionOptions
{
get
Expand All @@ -430,6 +429,7 @@ public static List<UnivariateDistributionType> DefaultDistributionOptions
(o != UnivariateDistributionType.KernelDensity) &&
(o != UnivariateDistributionType.Mixture) &&
(o != UnivariateDistributionType.NoncentralT) &&
(o != UnivariateDistributionType.UserDefined) &&
(o != UnivariateDistributionType.UniformDiscrete) &&
(o != UnivariateDistributionType.Poisson)).ToList();
}
Expand Down Expand Up @@ -504,7 +504,9 @@ public object Convert(object value, Type targetType, object parameter, CultureIn
UncertainOrderedPairedData val = value as UncertainOrderedPairedData;
if (val == null) return "";
if (val.Count > 0) return val[0].Y.DisplayName;
return UnivariateDistributionFactory.CreateDistribution(val.Distribution).DisplayName;
if (UnivariateDistributionFactory.TryCreateDistribution(val.Distribution, out var distribution) &&
distribution is not null) return distribution.DisplayName;
return val.Distribution.ToString();
}

/// <inheritdoc/>
Expand Down
Loading
Loading