PowerMVVM.Commands 1.0.7.6

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

// Install PowerMVVM.Commands as a Cake Tool
#tool nuget:?package=PowerMVVM.Commands&version=1.0.7.6                

PowerMVVM

A powerful, framework independent MVVM toolset.
Released under the MIT License

For changelog please see Releases
Find more information in the Wiki

PowerMVVM.Commands

The commanding library supports synchronous, as well as asynchronous commands. It provides all the features you're expecting of a command:

  • preventing execution when already running
  • handling asynchronous calls
  • handling errors during command execution
  • invalidating can execute when dependent upon a property
  • calling continuation actions on the initial context
  • configure await settings for the command actions
  • showing and hiding loading indicators
  • logging information when executing a command
  • command for long running CPU bound background tasks
  • an AutoResetCommand for fire-once purposes
  • new in Version 1.0.6: per command status providers

Usage is simplified by providing factory methods on the static Command class. It is possible to create generic, as well as non generic actions or Task based functions, with or without a CanExecute function. For extensibility, it also provides a wrapper to run any already existing ICommand. Factory methods for creating a singleton/lazy command are also available.

// command creation
Command.Create(Action action)
Command.Create(Action action, Func<bool> canExecute)
Command.Create<T>(Action<T> action)
Command.Create<T>(Action<T> action, Func<T, bool> canExecute)
Command.Create(Func<Task> action)
Command.Create<T>(Func<T, Task> action)
Command.Create(Func<Task> action, Func<bool> canExecute)
Command.Create<T>(Func<T, Task> action, Func<T, bool> canExecute)
Command.Create(ICommand command)

// command configuration
Command.Create(MyAction)
       .ContinueWith(MyContinuationAction)      // configure a continuation action
       .UseErrorHandler(MyErrorHandler)         // set an error handler
       .UseLoadingIndicator()                   // display the loading indicator (disabled by default)
       .UseLoadingIndicator(ILoadingIndicator)  // control an external loading indicator instance
       .UseLoadingIndicator(show, hide)         // control any loading states with show and hide callbacks
       .AllowMultipleExecution()                // disable the multi-execution prevention (enabled by default)
       .ContinueOncapturedContext()             // return to originating thread after command action execution (disabled by default)
       .ConfigureRaiseCanExecuteChanged(pco =>  // configure (or change) to automatically raise CanExecuteChanged
            pco.SetPropertyHolder(this)                         // when in the set view model
               .SubscribeToProperty(nameof(MyProperty))         // any of the subscribed properties change
       .AddRaiseCanExecuteChanged(pco =>        // configure to automatically raise CanExecuteChanged
            pco.SetPropertyHolder(anyViewModel)                         // when in one of the set view models
               .SubscribeToProperty(nameof(MyProperty))         // any of the subscribed properties change

// external services configuration
Command.LoggingProvider = (ILoggingProvider)provider;
Command.StatusProvider = (AStatusProvider)provider;
Command.AlwaysContinueOnCapturedContext = true;             // always return to the commands action context

Loading Indicators

Custom loading indicators can be added for each command via callback methods or via the ILoadingIndicator interface. The default indicator will not be shown. Instead you gain full control over the loading indicator, because it passes the command name and allows to show different layouts or text, depending on the command.

Default loading indicator for every command

Implementing a loading spinner is quite easy with PowerMVVM. You have to inherit from AStatusProvider and implement your calls to the UI framework.

Register the status provider via the static property:

Command.StatusProvider = new MyStatusProviderImplementation();

Logging

You can use your preferred logging framework or method by creating a logging provider inheriting from ILoggingProvider. This allows to gain information about

  • when the command was called and with which parameter
  • the exception that occured, in case an exception occured
  • when the command call completed

Register the LoggingProvider via the static property:

Command.LoggingProvider = new MyLoggingProviderImplementation();

Testability

For testability, the extension methods in PowerMVVM.Commands.Testability provide all necessary methods to test your internal implemetation. This allows to test your code, which means, that the test fails on errors in your code, instead of throwing an exception on the command.

using PowerMVVM.Commands.Testability;

var canExecute = myCommand.CanExecute()
var canExecute = myCommand.CanExecute<T>(T param)
await myCommand.ExecuteActionAsync()
await myCommand.ExecuteActionAsync<T>(T param)
myCommand.ExecuteContinuationAction()
myCommand.ExecuteErrorHandler(Exception exception)

Background Command

The special class BackgroundCommand supports long runing, CPU bound tasks. It is best used for fire-and-forget implementations, such as triggering an upload.
Cancellation, Errorhandling and Continuation Actions are supported as well. It also uses the standard logging provider (see above).
PowerMVVM.Commands.Testability provides all necessary methods to test your command's code.
Please use with care, to avoid memory leaks and strong references to your view models when the command might run for a really long time!

// background task signature
Task MyBackgroundTask(object commandParameter, CancellationToken token) { ... }

// command configuration
new BackgroundCommand(MyBackgroundTask, Func<bool> canExecute, initialConcurrentRequests, maximumConcurrentRequests);
    .ContinueWith(Action<object> continuationAction)
    .RegisterCancellationTokenFactory(Func<CancellationToken> factory)
    .SetCancellationHandler(Action cancellationHandler)
    .SetErrorHandler(Action<Exception> errorHandler)

Auto-Reset Command

The special class AutoResetCommand enables fire-once commands. Inspired by the AutoResetEvent of the framework, it just does nothing until it gets signalled. When it's time to evaluate and execute the command, it triggers exactly once, and resets itself to a non-signalled state, waiting for the next signal to wake it up.
Please note, that it will never block. It just gets ignored when not signalled.

// command configuration
new AutoResetCommand(syncOrAsyncAction)                 // creates a non signalled auto reset command
    .ContinueWith(Action continuationAction)
    .SetErrorHandler(Action<Exception> errorHandler)
    
myAutoResetCommand.Signal();    \\ tell the command, that it should run exactly one time on it's next call to execute

Extending PowerMVVM's commands

As mentioned before, it is possible to wrap any ICommand into a command, via the given factory method. Still you can create your own commands by inheriting from the abstract base class ACommand.

Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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. 
.NET Core netcoreapp2.0 is compatible.  netcoreapp2.1 is compatible.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 is compatible. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETCoreApp 2.0

    • No dependencies.
  • .NETCoreApp 2.1

    • No dependencies.
  • .NETCoreApp 3.1

    • No dependencies.
  • .NETStandard 2.0

    • No dependencies.
  • .NETStandard 2.1

    • No dependencies.
  • net5.0

    • No dependencies.

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.7.6 1,828 7/1/2022
1.0.7.1 830 4/15/2022
1.0.6 1,564 6/22/2021
1.0.5.4 681 4/7/2021
1.0.5 1,321 2/25/2021
1.0.4.80 630 2/19/2021
1.0.4.22 1,247 11/9/2020
1.0.4.20 743 11/6/2020
1.0.4.13 689 10/11/2020
1.0.4.7 863 10/8/2020
1.0.3.6 758 9/14/2020
1.0.2.27 855 8/15/2020
1.0.2.21 729 8/15/2020