LiteObservableRegions 1.2.2

dotnet add package LiteObservableRegions --version 1.2.2
                    
NuGet\Install-Package LiteObservableRegions -Version 1.2.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="LiteObservableRegions" Version="1.2.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="LiteObservableRegions" Version="1.2.2" />
                    
Directory.Packages.props
<PackageReference Include="LiteObservableRegions" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add LiteObservableRegions --version 1.2.2
                    
#r "nuget: LiteObservableRegions, 1.2.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package LiteObservableRegions@1.2.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=LiteObservableRegions&version=1.2.2
                    
Install as a Cake Addin
#tool nuget:?package=LiteObservableRegions&version=1.2.2
                    
Install as a Cake Tool

NuGet Actions

LiteObservableRegions

A lightweight, Prism-like region and navigation library for WPF. Define regions in XAML, navigate by URI, and resolve views from Microsoft.Extensions.DependencyInjection or from named host children.

Features

  • XAML-first regions — Attached properties ObservableRegion.RegionName and ObservableRegion.ViewName on any DependencyObject. The element with RegionName is the region host (content is displayed here); ViewName is set on a child of that host to register a named view.
  • URI-based navigation — Format region://RegionName/TargetName?query. Navigate (push), Redirect (replace and clear back stack), GoBack, GoForward per region. Region names are compared case-insensitively.
  • Two ways to resolve views
    • Named views — Set ViewName="region://RegionName/TargetName" on a child of the host; that element is used when navigating to that target (no DI). The host must already be registered (e.g. parent has RegionName); region name in ViewName must match the host’s region name (case-insensitive).
    • DI views — Register with AddObservableRegions(reg => reg.AddView<T>("TargetName", lifetime)) or AddRegionViews(...); views are resolved from the service provider (Transient, Scoped per region, Singleton). Scoped creates one scope per region; Singleton is cached per region+target.
  • Navigation stack — Per-region back and forward stacks. Redirect clears the back stack and does not push. Navigate to the same URI as current is a no-op (no stack or content change).
  • INavigationAware — Optional: implement on the view or on the view’s DataContext. OnNavigatedFrom(NavigationContext) and OnNavigatedTo(NavigationContext) receive FromUri, ToUri, Parameters, Mode, RegionName, TargetName; context.IsRedirect for Redirect.
  • Pluggable host adapterIRegionHostContentAdapter.SetContent(host, content). Register before AddObservableRegions to customize. Default: ContentControl→Content, Frame→Navigate(content), Panel/ItemsControl→add child and toggle visibility when IsPreferKeepAlive is true, else clear then add; Decorator→Child; other hosts→ObservableRegion.CurrentContent.
  • Region contextObservableRegion.RegionContext attached property for arbitrary data; no change notifications.
  • Region change notification — Subscribe to WeakReferenceRegionHub.EventNotifier.ObservableRegionChanged; raised before content changes (before OnNavigatedFrom/OnNavigatedTo). Args: RegionName, FromUri, ToUri, FromTargetName, ToTargetName, NavigationMode (Navigate, Redirect, GoBack, GoForward), and Cancel to abort the navigation.
  • Lifetime — Region host: when a FrameworkElement with RegionName implements <see cref="IRegionScope"/>, Unloaded unregisters the region and disposes its scope; otherwise the region is not removed on Unloaded (avoids “region not found” when the host is in a tab or lazy-loaded). Named view: when a FrameworkElement with ViewName implements IRegionScope, Unloaded removes that named view; otherwise it is not removed.

Installation

dotnet add package LiteObservableRegions

Targets: .NET Framework 4.6.2, 4.7.2, 4.8, 4.8.1; .NET 5–10 (Windows, WPF). Single package, multi-targeted.

Quick start

1. Register services and set the service provider

In app startup (e.g. App.xaml.cs), build the DI container and set the static service provider so XAML-attached registration can resolve IRegionManager:

using LiteObservableRegions;
using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();
services.AddObservableRegions(reg =>
{
    reg.AddView<PageA>("ViewA", ServiceLifetime.Scoped);
    reg.AddView<PageB>("ViewB", ServiceLifetime.Scoped);
});
// Optional: services.AddSingleton<IRegionHostContentAdapter, MyAdapter>();
var provider = services.BuildServiceProvider();
WeakReferenceRegionHub.ServiceProvider = provider;

2. Define a region in XAML

The host is the element that receives the active view (e.g. a ContentControl or a Grid). Set RegionName on that element. Accepts "region://Name" or "Name" (normalized by the library).

<ContentControl xmlns:r="http://schemas.github.com/liteobservableregions/2026/xaml"
	r:ObservableRegion.RegionName="MainRegion" />

Or use a Grid as host — content is set on the Grid via ObservableRegion.CurrentContent; bind a child (e.g. ContentPresenter) to that attached property on the ancestor, or use a single ContentControl as host instead.

Named views (no DI): set ViewName on a child of the host. The first path segment is the target name used for navigation.

<Grid r:ObservableRegion.RegionName="region://TestGridRegion">
    <Grid r:ObservableRegion.ViewName="region://TestGridRegion/View1" />
    <Grid r:ObservableRegion.ViewName="region://TestGridRegion/View2" />
</Grid>

Here the host is the outer Grid; content is shown via CurrentContent on that Grid. For a single child host like ContentControl, put RegionName on the ContentControl so content goes to Content.

3. Navigate

IRegionManager manager = WeakReferenceRegionHub.RegionManager;

manager.Navigate(new Uri("region://MainRegion/ViewA"));   // push onto back stack
manager.Redirect(new Uri("region://MainRegion/ViewB"));   // replace, clear back stack

if (manager.CanGoBack("MainRegion"))
    manager.GoBack("MainRegion");
if (manager.CanGoForward("MainRegion"))
    manager.GoForward("MainRegion");

IRegion region = manager.GetRegion("MainRegion");
Uri current = region?.CurrentUri;
object host = region?.Host;   // IRegion: Name, Host, CurrentUri, CanGoBack, CanGoForward

Advanced: manager.Regions is a Dictionary<string, RegionState> (Host, BackStack, ForwardStack, CurrentEntry, NamedViews, Scope).

4. Region change notification and cancellation

WeakReferenceRegionHub.EventNotifier.ObservableRegionChanged is raised before the region content is updated. Set e.Cancel = true to prevent the navigation.

WeakReferenceRegionHub.EventNotifier.ObservableRegionChanged += (sender, e) =>
{
    // e.RegionName, e.FromUri, e.ToUri, e.FromTargetName, e.ToTargetName, e.Mode, e.Cancel
    if (someCondition)
        e.Cancel = true;
};

e.Mode is NavigationMode: Navigate, Redirect, GoBack, GoForward.

Region URIs

  • Format: region://RegionName/TargetName?param1=value1&param2=value2
  • Scheme: RegionUriParser.Scheme ("region").
  • Region name — Authority part; must match a registered region. Preserved casing (URI host is not used for casing).
  • Target name — First path segment; view identifier (named view or registry key).
  • Query — Optional; parsed into NavigationContext.Parameters and passed to INavigationAware.

Helpers:

  • RegionUriParser.NormalizeRegionName(value) — strips region:// prefix if present.
  • RegionUriParser.TryParse(uri, out regionName, out targetName, out parameters) — returns false if scheme or target missing.
  • RegionUriParser.ParseQuery(query) — returns dictionary of query parameters.
  • RegionUriParser.BuildUri(regionName, targetName, parameters) — parameters optional.

For navigation you must include a target: region://MainRegion/View1. Region name only (region://MainRegion) is valid for RegionName in XAML; the library normalizes it.

Attached properties (ObservableRegion)

Property Type Description
RegionName string On the host element. Registers the element as a region. Accepts "region://Name" or "Name".
ViewName string On a child of the host. Value like region://RegionName/View1; the child is registered as the view for that target (no DI).
CurrentContent object Set by the library; current view in the region. Can be bound.
RegionContext object Arbitrary data; no change handling.

View resolution order

When navigating to a target name in a region:

  1. Named views — If the region has a view registered for that name (via ViewName), that instance is used (weak reference; re-resolved from DI if collected).
  2. DI — Otherwise resolved from IRegionViewRegistry and IServiceProvider: Transient (new each time), Scoped (per-region scope), Singleton (cached per region+target).

Register view types with AddObservableRegions(reg => reg.AddView<T>("TargetName", ServiceLifetime.Scoped)) or, for registry only, AddRegionViews(reg => ...) then register IRegionManager yourself.

Customizing how content is displayed

Implement IRegionHostContentAdapter (single method: SetContent(DependencyObject host, object content)) and register it in DI before AddObservableRegions. The default adapter:

  • ContentControl → set Content
  • FrameNavigate(content)
  • Panel / ItemsControl → if IsPreferKeepAlive is true (default): add child if not present, then set visibility (active = Visible, others = Collapsed); if false: clear then add
  • Decorator → set Child
  • Any other host → ObservableRegion.SetCurrentContent(host, content)

Duplicate names and cleanup

  • Same RegionName — Registering again replaces the previous region: existing scope is disposed, new host is the only one for that name.
  • Same ViewName (same region) — Registering again overwrites the previous named view for that target.

Clear: WeakReferenceRegionHub.Clear() (or IRegionManager.Clear()) clears all named views and the singleton view cache; does not unregister regions or navigation stacks.

API overview

  • LiteObservableRegions: WeakReferenceRegionHub (ServiceProvider, RegionManager, EventNotifier, Clear), ObservableRegion, RegionUriParser, RegionChangedEventArgs, NavigationMode, NavigationContext, DefaultRegionHostContentAdapter, RegionServiceCollectionExtensions (AddRegionViews, AddObservableRegions), RegionManager, RegionState, ViewRegistration, NavigationEntry.
  • LiteObservableRegions.Abstractions: IRegionManager, IRegionNavigation, IRegion, IRegionViewRegistry, IRegionHostContentAdapter, INavigationAware, IRegionScope.

License

MIT

Product Compatible and additional computed target framework versions.
.NET net5.0-windows7.0 is compatible.  net6.0-windows was computed.  net6.0-windows7.0 is compatible.  net7.0-windows was computed.  net7.0-windows7.0 is compatible.  net8.0-windows was computed.  net8.0-windows7.0 is compatible.  net9.0-windows was computed.  net9.0-windows7.0 is compatible.  net10.0-windows was computed.  net10.0-windows7.0 is compatible. 
.NET Framework net462 is compatible.  net463 was computed.  net47 was computed.  net471 was computed.  net472 is compatible.  net48 is compatible.  net481 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.2 88 2/27/2026
1.2.1 90 2/27/2026
1.2.0 87 2/27/2026
1.1.0 95 2/27/2026
1.0.0 90 2/26/2026