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
<PackageReference Include="PowerMVVM.Commands" Version="1.0.7.6" />
paket add PowerMVVM.Commands --version 1.0.7.6
#r "nuget: PowerMVVM.Commands, 1.0.7.6"
// 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 | Versions 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. |
-
.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 |