Singulink.UI.Navigation.MvvmToolkit 1.0.0

Prefix Reserved
dotnet add package Singulink.UI.Navigation.MvvmToolkit --version 1.0.0                
NuGet\Install-Package Singulink.UI.Navigation.MvvmToolkit -Version 1.0.0                
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="Singulink.UI.Navigation.MvvmToolkit" Version="1.0.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Singulink.UI.Navigation.MvvmToolkit --version 1.0.0                
#r "nuget: Singulink.UI.Navigation.MvvmToolkit, 1.0.0"                
#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.
// Install Singulink.UI.Navigation.MvvmToolkit as a Cake Addin
#addin nuget:?package=Singulink.UI.Navigation.MvvmToolkit&version=1.0.0

// Install Singulink.UI.Navigation.MvvmToolkit as a Cake Tool
#tool nuget:?package=Singulink.UI.Navigation.MvvmToolkit&version=1.0.0                

Chat on Discord

UI Toolkit provides components that are generally useful for UI applications with a strong emphasis on testability of view models. It is currently focused on WinUI and Uno-based applications but some components are UI framework-agnostic. Details of each component are provided below.

Library Status Package
Singulink.UI.Navigation Preview View nuget package
Singulink.UI.Navigation.MvvmToolkit Preview View nuget package
Singulink.UI.Navigation.WinUI Preview View nuget package
Singulink.UI.Tasks Public View nuget package
Singulink.UI.Xaml.WinUI Public View nuget package

Libraries may be in any of the following states:

  • Internal: Source code (and possibly a nuget package) is available to the public but the library is intended to be used internally until further development.
  • Preview: The library is available for public preview but the APIs may not be fully documented and the API surface is subject to change without notice.
  • Public: The library is intended for public use with a fully documented and stable API surface.

You are free to use any libraries or code in this repository that you find useful and feedback/contributions are welcome regardless of library state.

We are a small team of engineers and designers dedicated to building beautiful, functional, and well-engineered software solutions. We offer very competitive rates as well as fixed-price contracts and welcome inquiries to discuss any custom development / project support needs you may have.

This package is part of our Singulink Libraries collection. Visit https://github.com/Singulink to see our full list of publicly available libraries and other open-source projects.

Components

Singulink.UI.Navigation

Strongly-typed AOT-friendly navigation framework with comprehensive deep-linking support. The base library is UI framework-agnostic and can be referenced from framework-agnostic view model projects, but currently only a WinUI/Uno-specific INavigator implementation is provided via the Singulink.UI.Navigation.WinUI package to do the actual navigation and routing in the UI app layer. Can be extended to support other UI frameworks, and contributions are welcome.

There is an additional 'Singulink.UI.Navigation.MvvmToolkit' package that provides base implementations of routed view models that inherit from the MVVM Community Toolkit's ObservableObject type.

Supported Platforms: .NET 8.0+, WinUI (WinAppSDK), Uno Platform 5.2+

Singulink.UI.Tasks

Provides a DI-friendly and UI framework-agnostic task runner/dispatcher with integrated support for managing UI busy-state while tasks are running. Supports running "fire-and-forget" tasks that can be tracked and fully tested. Inspired by AmbientTasks (thanks @jnm2)

Example fire-and-forget usage:

public class App
{
  public static ITaskRunner TaskRunner { get; private set; }

  public void OnAppStart()
  {
    TaskRunner = new TaskRunner(
      busy => YourRootControl.IsEnabled = !busy);
  }
}

public class YourViewModel(ITaskRunner taskRunner)
{
  public ObservableCollection<Item> Items { get; } = [];

  public void OnNavigatedTo()
  {
    // YourRootControl.IsEnabled will be false while this runs

    taskRunner.RunAndForget(setBusy: true, async () =>
    {
      var items = await LoadItemsAsync();

      foreach (var item in items)
      {
        Items.Add(item);
      }
    });
    }
}

Our philosophy is that testing view models without a proper synchronization context is asking for trouble, so TaskRunner requires one. The AsyncEx.Context library has a perfect AsyncContext class that can be used for this purpose. Your test would then look something like this:

[TestClass]
public class YourViewModelTests
{
  [TestMethod]
  public void TestLoadsItemsAsync()
  {
    AsyncContext.Run(async () =>
    {
      var taskRunner = new TaskRunner();

      var vm = new YourViewModel(taskRunner);
      vm.OnNavigatedTo();

      // Wait for all busy tasks to complete
      await taskRunner.WaitForIdleAsync();

      Assert.AreEqual(3, vm.Items.Count);
    });
  }
}

Supported Platforms: .NET 8.0+, any UI framework (i.e. UWP/WinUI, Uno Platform, Avalonia, WPF, etc)

Singulink.UI.Xaml.WinUI

Contains useful XAML extensions (behaviors, converters, static convert methods for use with x:Bind) for WinUI and Uno-based applications.

Here is a small sampling of the massive collection of static convert methods available:

xmlns:suxc="using:Singulink.UI.Xaml.Converters"

IsEnabled="{x:Bind suxc:If.Zero(Model.Items.Count)}"
IsEnabled="{x:Bind suxc:If.NotZero(Model.Items.Count)}"
IsEnabled="{x:Bind suxc:If.Null(Model.Item)}"
IsEnabled="{x:Bind suxc:If.NotNullOrWhiteSpace(Model.Name)}"
IsEnabled="{x:Bind suxc:If.NotDefault(Model.SomeEnumValue)}"

Visibility="{x:Bind suxc:Visible.IfEqualsAnyString(Model.EnumValue, 'EnumName1', 'EnumName2')}"
Visibility="{x:Bind suxc:Visible.IfFocused(SomeOtherControl.FocusState)}"
Visibility="{x:Bind suxc:Visible.IfFalse(Model.Hide)}"

Opacity="{x:Bind suxc:Opaque.IfTrue(Model.ShowValue)}"}

Uri="{x:Bind suxc:Uri.Email(Model.EmailString)}"
Uri="{x:Bind suxc:Uri.Phone(Model.PhoneString)}"
Uri="{x:Bind suxc:Uri.Website(Model.WebsiteString)}"

Supported Platforms: .NET 8.0+, WinUI (WinAppSDK), Uno Platform 5.2+

Further Reading

You can view API documentation on the project documentation site.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net8.0-windows10.0.19041 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.0.0 82 10/29/2024