CrissCross.WinForms
3.2.2
dotnet add package CrissCross.WinForms --version 3.2.2
NuGet\Install-Package CrissCross.WinForms -Version 3.2.2
<PackageReference Include="CrissCross.WinForms" Version="3.2.2" />
<PackageVersion Include="CrissCross.WinForms" Version="3.2.2" />
<PackageReference Include="CrissCross.WinForms" />
paket add CrissCross.WinForms --version 3.2.2
#r "nuget: CrissCross.WinForms, 3.2.2"
#:package CrissCross.WinForms@3.2.2
#addin nuget:?package=CrissCross.WinForms&version=3.2.2
#tool nuget:?package=CrissCross.WinForms&version=3.2.2
CrissCross
A navigation framework and set of UI components for ReactiveUI-based applications across WPF, Avalonia, MAUI, and WinForms.
Overview
CrissCross provides ViewModel-first navigation, hostable navigation surfaces, and a comprehensive WPF UI control set with a strong ReactiveUI focus. It promotes:
- ViewModel-first navigation using ReactiveUI�s IViewFor and WhenActivated
- Host-based navigation via named ViewModelRoutedViewHost containers
- Consistent navigation lifecycle notifications (WhenNavigating/WhenNavigatedTo/From)
- Easy DI/IoC integration via Splat and Microsoft.Extensions.Hosting
- A large library of fluent WPF UI controls and services (dialogs, snackbars, themes)
Supported platforms and packages:
- Core: CrissCross (ReactiveUI helpers and navigation abstractions)
- WPF navigation host: CrissCross.WPF
- WPF UI control library: CrissCross.WPF.UI
- Avalonia host: CrissCross.Avalonia
- .NET MAUI helpers: CrissCross.MAUI
- WinForms host: CrissCross.WinForms
- WPF WebView2 overlay host: CrissCross.WPF.WebView2
- WPF Plot control suite: CrissCross.WPF.Plot
NuGet packages:
- CrissCross:
- WPF:
- WPF UI:
- Avalonia:
- MAUI:
- WinForms:
- WPF WebView2:
- WPF Plot:
Note: Xamarin.Forms support exists in separate projects but for new apps prefer .NET MAUI.
Breaking Changes in Version 3.2.0 +
- Using a new version of ReactiveUI (v23.1+) with some API changes, the main change is the registration of ReactiveUI components which now uses an AppBuilder fluent API instead of Splat�s locator directly. This is a breaking change but allows for better integration with AoT builds and more flexible registration patterns.
- Add
RxAppBuilder.CreateReactiveUIBuilder().With**Platform**().BuildApp();as early as possible in your app startup (e.g., App.xaml.cs) to register ReactiveUI services. Then register your VMs/Views as usual with Splat or Microsoft.Extensions.DependencyInjection. - RxApp has been completely removed, so any direct references to RxApp.Current or RxApp.MainThreadScheduler should be updated to use the new builder pattern and new service resolution.
Core Concepts
CrissCross builds on ReactiveUI to provide ViewModel-first navigation:
- IRxObject: Base ViewModel type used throughout CrissCross
- IViewFor<TViewModel>: ReactiveUI contract mapping VMs to Views
- WhenActivated: ReactiveUI activation lifecycle for Views
- ViewModelRoutedViewHost: Navigation host control that manages a navigation stack and view transitions
- HostName: A host identifier (string) that allows targeting navigation to a specific host
- Navigation lifecycle: WhenNavigating, WhenNavigatedTo, WhenNavigatedFrom via mixins/events
Register your ViewModels and Views with Splat�s Locator or Microsoft.Extensions.DependencyInjection. CrissCross uses the locator to resolve Views for navigation targets.
Quick Start (WPF)
- Install packages
- CrissCross
- CrissCross.WPF
- CrissCross.WPF.UI (for controls/themes)
- Register ViewModels and Views
public class AppBootstrapper : RxObject
{
public AppBootstrapper()
{
this.BuildComplete(() =>
{
// Example VM/View registrations using Splat
AppLocator.CurrentMutable.RegisterConstant(new MainViewModel());
AppLocator.CurrentMutable.Register<IViewFor<MainViewModel>>(() => new MainView());
AppLocator.CurrentMutable.RegisterConstant(new FirstViewModel());
AppLocator.CurrentMutable.Register<IViewFor<FirstViewModel>>(() => new FirstView());
AppLocator.CurrentMutable.SetupComplete();
});
}
}
- Create a navigation host (NavigationWindow)
public partial class MainWindow : NavigationWindow<MainWindowViewModel>
{
public MainWindow()
{
InitializeComponent(); // Ensure x:Name is set on the Window (e.g., "mainWindow")
this.WhenActivated(d =>
{
// Bind back command, etc
NavBack.Command = ReactiveCommand.Create(() => this.NavigateBack(), CanNavigateBack).DisposeWith(d);
// Navigate to a start VM
this.NavigateToView<MainViewModel>();
});
}
}
- Navigate from a ViewModel
public class MainViewModel : RxObject
{
public MainViewModel()
{
this.BuildComplete(() =>
{
// Target a specific host by name (Window x:Name)
this.NavigateToView<FirstViewModel>("mainWindow");
});
}
}
- Create a View
public partial class MainView : ReactiveUserControl<MainViewModel>
{
public MainView()
{
InitializeComponent();
this.WhenActivated(_ => { /* bindings, commands */ });
}
}
Hosts and Navigation APIs
NavigationWindow (WPF): A Window that exposes a ViewModelRoutedViewHost and transition support
- Properties: Transition, NavigateBackIsEnabled
- Exposes CanNavigateBack observable and NavigateBack() helper
FluentNavigationWindow (WPF UI): A fluent-styled NavigationWindow with additional title content areas and Transition
NavigationUserControl (WPF UI, Avalonia): A hostable control version of the navigation container (for regions/panels)
ViewModelRoutedViewHost (WPF): Core host implementation
- Navigate<TViewModel>(contract, parameter)
- Navigate(IRxObject vm, contract, parameter)
- NavigateAndReset variants
- NavigateBack(parameter)
- CanNavigateBackObservable, NavigationStack
- Lifecycle events routed via ViewModelRoutedViewHostMixins:
- WhenNavigating: preview/cancel navigation
- WhenNavigatedTo/From: after navigation completes
HostName: Set on NavigationWindow/NavigationUserControl (typically from x:Name) to route cross-host navigation
Navigation from Views and ViewModels
- From code-behind: this.NavigateToView<TViewModel>(hostName?, parameter?)
- From ViewModel: this.NavigateToView<TViewModel>(hostName, parameter?)
- NavigateBack(hostName?, parameter?) and CanNavigateBack(hostName?) helpers
WPF UI Library (CrissCross.WPF.UI)
A comprehensive set of fluent controls and services designed for ReactiveUI apps. Highlights include:
- NavigationView, BreadcrumbBar and navigation controls/models
- Dialogs: ContentDialog, MessageBox, async variants
- Notifications: Snackbar, InfoBar, InfoBadge
- Input: AutoSuggestBox, NumberBox, PasswordBox, ToggleSwitch, TimePicker, DatePicker
- Lists and virtualization: ListView, VirtualizingGridView, VirtualizingWrapPanel
- Layout/containers: Card, CardExpander, GroupBox, Grid, StackPanel
- Media: GifImage (animation), Image
- PersonPicture, RatingControl, ProgressRing, AppBar, TitleBar, Window enhancements
- Color controls: ColorSelector suite (sliders, dual pickers), HexColorTextBox, and ColorPicker
- Typography and iconography: FontIcon, SymbolIcon, IconSource
- Themes and appearance utilities
Include the control resources by merging the ControlsDictionary:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ui:ControlsDictionary />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Theming and Appearance
- ApplicationThemeManager and SystemThemeWatcher for light/dark and system theme integration
- Resource dictionaries for typography, colors, focus, default styles
- ThemeService and IThemeService for programmatic control
Services
- ContentDialogService: Show dialogs and await results
- SnackbarService: Host snackbars with extension helpers
- PageService (WPF UI): Resolve pages by type for embedded/hosted scenarios
WPF Page Navigation (Host Builder)
For page-based apps using WPF UI, use the host builder extensions:
private static readonly IHost _host = Host.CreateDefaultBuilder()
.ConfigureCrissCrossForPageNavigation<MainWindow, DashboardPage>()
.ConfigureServices((context, services) =>
{
services.AddSingleton<MainWindowViewModel>();
services.AddSingleton<DashboardPage>().AddSingleton<DashboardViewModel>();
services.AddSingleton<DataPage>().AddSingleton<DataViewModel>();
services.AddSingleton<SettingsPage>().AddSingleton<SettingsViewModel>();
services.AddSingleton<LoginPage>().AddSingleton<LoginViewModel>();
})
.Build();
Wire up and start in App.xaml.cs, then navigate using IPageService or NavigationView.
NavigationView (WPF UI)
A powerful navigation control that manages a journal and hierarchical navigation stack:
- Navigate(Type pageType, object? dataContext)
- Navigate(string pageIdOrTargetTag, object? dataContext)
- NavigateWithHierarchy(Type pageType, object? dataContext)
- ReplaceContent(Type pageType) / ReplaceContent(UIElement)
- GoBack(), GoForward() (where implemented), ClearJournal()
- Events: Navigating (cancelable), Navigated, BackRequested, SelectionChanged, PaneOpened/Closed
The control maintains a NavigationStack and history so you can build rich shell navigation experiences.
Avalonia
- NavigationUserControl (host)
- ViewModelRoutedViewHost equivalent with CanNavigateBack observable and HostName
- Use ReactiveUI�s WhenActivated and Splat for registration as in WPF
public partial class MainUserControl : NavigationUserControl<MainWindowViewModel>
{
public MainUserControl()
{
InitializeComponent();
this.WhenActivated(d =>
{
this.NavigateToView<MainViewModel>();
_NavBack!.Command = ReactiveCommand.Create(() => this.NavigateBack(), this.CanNavigateBack()).DisposeWith(d);
});
}
}
.NET MAUI
MAUI helpers integrate with ReactiveUI.Maui. Register your VMs/Views with DI and navigate using the same NavigateToView/Back helpers where applicable. Prefer this approach over Xamarin.Forms for new apps.
Packages:
- CrissCross.MAUI
- ReactiveUI.Maui
WinForms
- ViewModelRoutedViewHost for WinForms
- ReactiveUserControl<TViewModel> usage with WhenActivated
- Navigate using the same helper mixins
WPF WebView2 Overlay Host
CrissCross.WPF.WebView2 provides a NavigationWebView that hosts WebView2 while allowing WPF content overlays:
xmlns:webv="https://github.com/reactivemarbles/CrissCross"
<webv:WebView2Wpf x:Name="WebView2Wpf" AutoDispose="True">
</webv:WebView2Wpf>
WebView2Wpf.Source = new Uri("https://www.reactiveui.net/");
WPF Plot (ScottPlot-based)
CrissCross.WPF.Plot adds Reactive plotting components:
- Bind reactive sequences
- Multiple series, Y-axes, crosshairs
- Zoom/pan, drag zoom selection
- Visibility toggles, auto/manual scale
Install: Install-Package CrissCross.WPF.Plot
Settings and Tracking (WPF UI)
Persist and track control/window state:
- Tracker service with attributes (Trackable, PersistOn, StopTrackingOn)
- Example usage in App.xaml.cs wiring window size/position persistence
_tracker?.Configure<MainWindow>()
.Id(w => w.Name, $"[Width={SystemParameters.VirtualScreenWidth},Height{SystemParameters.VirtualScreenHeight}]")
.Properties(w => new { w.Height, w.Width, w.Left, w.Top, w.WindowState })
.PersistOn(w => nameof(w.Closing))
.StopTrackingOn(w => nameof(w.Closing));
Color and Media Controls (WPF UI)
- ColorSelector suite (HSV/HSL/RGB sliders, square pickers, hex entry, dual color with hints)
- ColorPicker control: A simple RGBA + Hex picker with a live preview
- GifImage with animation control and performance-oriented decoding/animation components
Samples
- CrissCross.WPF.UI.Test: WPF UI test app with page navigation
- CrissCross.WPF.Test: WPF navigation sample
- CrissCross.Avalonia.Test.*: Avalonia samples (desktop, mobile)
- CrissCross.MAUI.Test: MAUI sample
- CrissCross.WPF.Plot.Test: Plot samples
- CrissCross.WPF.WebView2.Test: WebView2 overlay usage
- CrissCross.WPF.UI.Gallery: Control gallery showcasing WPF UI controls
Browse these projects to see real-world usage patterns, navigation setup, and control bindings.
Single Instance (WPF)
Prevent multiple instances using Make.SingleInstance in App:
protected override void OnStartup(StartupEventArgs e)
{
Make.SingleInstance("MyUniqueAppName ddd81fc8-9107-4e33-b848-cac4c3ec3d2a");
base.OnStartup(e);
}
Contributing
Issues and PRs are welcome. Please include platform, .NET version, and a minimal repro where applicable.
License
MIT � ReactiveUI Association Incorporated
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0-windows10.0.19041 is compatible. net9.0-windows was computed. net9.0-windows10.0.19041 is compatible. net10.0-windows was computed. net10.0-windows10.0.19041 is compatible. |
| .NET Framework | net472 is compatible. net48 was computed. net481 is compatible. |
-
.NETFramework 4.7.2
- CrissCross (>= 3.2.2)
- ReactiveUI (>= 23.1.8)
- ReactiveUI.WinForms (>= 23.1.8)
- System.Buffers (>= 4.6.1)
- System.Memory (>= 4.6.3)
-
.NETFramework 4.8.1
- CrissCross (>= 3.2.2)
- ReactiveUI (>= 23.1.8)
- ReactiveUI.WinForms (>= 23.1.8)
- System.Buffers (>= 4.6.1)
- System.Memory (>= 4.6.3)
-
net10.0-windows10.0.19041
- CrissCross (>= 3.2.2)
- ReactiveUI (>= 23.1.8)
- ReactiveUI.WinForms (>= 23.1.8)
-
net8.0-windows10.0.19041
- CrissCross (>= 3.2.2)
- ReactiveUI (>= 23.1.8)
- ReactiveUI.WinForms (>= 23.1.8)
-
net9.0-windows10.0.19041
- CrissCross (>= 3.2.2)
- ReactiveUI (>= 23.1.8)
- ReactiveUI.WinForms (>= 23.1.8)
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 |
|---|---|---|
| 3.2.2 | 51 | 3/9/2026 |
| 3.1.4 | 108 | 1/13/2026 |
| 3.0.2 | 105 | 1/12/2026 |
| 2.6.60 | 109 | 1/7/2026 |
| 2.6.57 | 113 | 1/5/2026 |
| 2.6.55 | 201 | 12/22/2025 |
| 2.6.22 | 702 | 12/2/2025 |
| 2.6.20 | 362 | 11/17/2025 |
| 2.6.17 | 315 | 11/12/2025 |
| 2.6.14 | 182 | 11/8/2025 |
| 2.6.2 | 322 | 9/15/2025 |
| 2.5.4 | 226 | 9/2/2025 |
| 2.5.3 | 207 | 9/1/2025 |
| 2.5.2 | 233 | 6/24/2025 |
| 2.5.1 | 369 | 6/12/2025 |
| 2.5.0 | 201 | 5/31/2025 |
| 2.4.1 | 299 | 4/1/2025 |
| 2.4.0 | 277 | 4/1/2025 |
| 2.3.0 | 259 | 3/28/2025 |
| 2.2.8 | 234 | 3/16/2025 |
Compatability with Net 8/9/10 and net4.7.2 / net4.8.1