diff --git a/.gitignore b/.gitignore
index ecd939e..34d15f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -226,3 +226,4 @@ pip-log.txt
.mr.developer.cfg
XamarinEvolve.userprefs
+/MvvmHelpers/MvvmHelpers.xml
diff --git a/MvvmHelpers/Commands/AsyncCommand.cs b/MvvmHelpers/Commands/AsyncCommand.cs
index 25101c0..1c72fa1 100644
--- a/MvvmHelpers/Commands/AsyncCommand.cs
+++ b/MvvmHelpers/Commands/AsyncCommand.cs
@@ -20,6 +20,13 @@ public class AsyncCommand : IAsyncCommand
readonly bool continueOnCapturedContext;
readonly WeakEventManager weakEventManager = new WeakEventManager();
+ ///
+ /// Create a new AsyncCommand
+ ///
+ /// Function to execute
+ /// Function to call to determine if it can be executed
+ /// Action callback when an exception occurs
+ /// If the context should be captured on exception
public AsyncCommand(Func execute,
Func canExecute = null,
Action onException = null,
@@ -31,16 +38,31 @@ public AsyncCommand(Func execute,
this.continueOnCapturedContext = continueOnCapturedContext;
}
+ ///
+ /// Event triggered when Can Excecute changes.
+ ///
public event EventHandler CanExecuteChanged
{
add { weakEventManager.AddEventHandler(value); }
remove { weakEventManager.RemoveEventHandler(value); }
}
+ ///
+ /// Invoke the CanExecute method and return if it can be executed.
+ ///
+ /// Parameter to pass to CanExecute.
+ /// If it can be executed.
public bool CanExecute(object parameter) => canExecute?.Invoke(parameter) ?? true;
+ ///
+ /// Execute the command async.
+ ///
+ /// Task of action being executed that can be awaited.
public Task ExecuteAsync() => execute();
+ ///
+ /// Raise a CanExecute change event.
+ ///
public void RaiseCanExecuteChanged() => weakEventManager.HandleEvent(this, EventArgs.Empty, nameof(CanExecuteChanged));
#region Explicit implementations
@@ -59,6 +81,13 @@ public class AsyncCommand : IAsyncCommand
readonly bool continueOnCapturedContext;
readonly WeakEventManager weakEventManager = new WeakEventManager();
+ ///
+ /// Create a new AsyncCommand
+ ///
+ /// Function to execute
+ /// Function to call to determine if it can be executed
+ /// Action callback when an exception occurs
+ /// If the context should be captured on exception
public AsyncCommand(Func execute,
Func canExecute = null,
Action onException = null,
@@ -70,16 +99,31 @@ public AsyncCommand(Func execute,
this.continueOnCapturedContext = continueOnCapturedContext;
}
+ ///
+ /// Event triggered when Can Excecute changes.
+ ///
public event EventHandler CanExecuteChanged
{
add { weakEventManager.AddEventHandler(value); }
remove { weakEventManager.RemoveEventHandler(value); }
}
+ ///
+ /// Invoke the CanExecute method and return if it can be executed.
+ ///
+ /// Parameter to pass to CanExecute.
+ /// If it can be executed
public bool CanExecute(object parameter) => canExecute?.Invoke(parameter) ?? true;
+ ///
+ /// Execute the command async.
+ ///
+ /// Task that is executing and can be awaited.
public Task ExecuteAsync(T parameter) => execute(parameter);
+ ///
+ /// Raise a CanExecute change event.
+ ///
public void RaiseCanExecuteChanged() => weakEventManager.HandleEvent(this, EventArgs.Empty, nameof(CanExecuteChanged));
#region Explicit implementations
diff --git a/MvvmHelpers/Commands/Command.cs b/MvvmHelpers/Commands/Command.cs
index 23b3a73..61e9c2b 100644
--- a/MvvmHelpers/Commands/Command.cs
+++ b/MvvmHelpers/Commands/Command.cs
@@ -10,6 +10,10 @@ namespace MvvmHelpers.Commands
///
public class Command : Command
{
+ ///
+ /// Command that takes an action to execute
+ ///
+ /// The action to execute of type T
public Command(Action execute)
: base(o =>
{
@@ -23,6 +27,11 @@ public Command(Action execute)
}
}
+ ///
+ /// Command that takes an action to execute
+ ///
+ /// The action to execute of type T
+ /// Function to call to determine if it can be executed.
public Command(Action execute, Func canExecute)
: base(o =>
{
@@ -49,22 +58,40 @@ public class Command : ICommand
readonly Action execute;
readonly WeakEventManager weakEventManager = new WeakEventManager();
+ ///
+ /// Command that takes an action to execute.
+ ///
+ /// Action to execute.
public Command(Action execute)
{
this.execute = execute ?? throw new ArgumentNullException(nameof(execute));
}
+ ///
+ /// Command that takes an action to execute.
+ ///
+ /// Action to execute.
public Command(Action execute) : this(o => execute())
{
if (execute == null)
throw new ArgumentNullException(nameof(execute));
}
+ ///
+ /// Command that takes an action to execute.
+ ///
+ /// Action to execute.
+ /// Function to determine if can execute.
public Command(Action execute, Func canExecute) : this(execute)
{
this.canExecute = canExecute ?? throw new ArgumentNullException(nameof(canExecute));
}
+ ///
+ /// Command that takes an action to execute.
+ ///
+ /// Action to execute.
+ /// Function to determine if can execute.
public Command(Action execute, Func canExecute) : this(o => execute(), o => canExecute())
{
if (execute == null)
@@ -73,16 +100,31 @@ public Command(Action execute, Func canExecute) : this(o => execute(), o =
throw new ArgumentNullException(nameof(canExecute));
}
+ ///
+ /// Invoke the CanExecute method to determine if it can be executed.
+ ///
+ /// Parameter to test and pass to CanExecute.
+ /// If it can be executed.
public bool CanExecute(object parameter) => canExecute?.Invoke(parameter) ?? true;
+ ///
+ /// Event handler raised when CanExecute changes.
+ ///
public event EventHandler CanExecuteChanged
{
add { weakEventManager.AddEventHandler(value); }
remove { weakEventManager.RemoveEventHandler(value); }
}
+ ///
+ /// Execute the command with or without a parameter.
+ ///
+ /// Parameter to pass to execute method.
public void Execute(object parameter) => execute(parameter);
+ ///
+ /// Manually raise a CanExecuteChanged event.
+ ///
public void RaiseCanExecuteChanged() => weakEventManager.HandleEvent(this, EventArgs.Empty, nameof(CanExecuteChanged));
}
}
diff --git a/MvvmHelpers/MvvmHelpers.csproj b/MvvmHelpers/MvvmHelpers.csproj
index 60d9406..090dc21 100644
--- a/MvvmHelpers/MvvmHelpers.csproj
+++ b/MvvmHelpers/MvvmHelpers.csproj
@@ -1,4 +1,4 @@
-
+
net461;netstandard1.0;netstandard2.0
@@ -12,7 +12,7 @@
true
https://raw.githubusercontent.com/jamesmontemagno/mvvm-helpers/master/art/Icon.png
en
- https://raw.githubusercontent.com/jamesmontemagno/mvvm-helpers/master/LICENSE.md
+ MIT
James Montemagno
https://github.com/jamesmontemagno/mvvm-helpers
Collection of MVVM Helpers such as ObservableRangeCollection, BaseViewModel, Grouping, and others.
@@ -43,6 +43,18 @@
$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
+
+ true
+
+ 4
+ C:\Users\jamont\Source\Repos\jamesmontemagno\mvvm-helpers\MvvmHelpers\MvvmHelpers.xml
+
+
+
+ true
+
+
+
diff --git a/MvvmHelpers/Utils.cs b/MvvmHelpers/Utils.cs
index b5373ec..48a032b 100644
--- a/MvvmHelpers/Utils.cs
+++ b/MvvmHelpers/Utils.cs
@@ -36,6 +36,12 @@ public static Task WithTimeout(this Task task, TimeSpan timeout) =>
WithTimeout(task, (int)timeout.TotalMilliseconds);
#pragma warning disable RECS0165 // Asynchronous methods should return a Task instead of void
+ ///
+ /// Attempts to await on the task and catches exception
+ ///
+ /// Task to execute
+ /// What to do when method has an exception
+ /// If the context should be captured.
public static async void SafeFireAndForget(this Task task, Action onException = null, bool continueOnCapturedContext = false)
#pragma warning restore RECS0165 // Asynchronous methods should return a Task instead of void
{
diff --git a/MvvmHelpers/WeakEventManager.cs b/MvvmHelpers/WeakEventManager.cs
index b9b5b5d..28aaf3e 100644
--- a/MvvmHelpers/WeakEventManager.cs
+++ b/MvvmHelpers/WeakEventManager.cs
@@ -7,10 +7,19 @@
namespace MvvmHelpers
{
+ ///
+ /// Weak event manager to subscribe and unsubscribe from events.
+ ///
public class WeakEventManager
{
readonly Dictionary> eventHandlers = new Dictionary>();
+ ///
+ /// Add an event handler to the manager.
+ ///
+ /// Event handler of T
+ /// Handler of the event
+ /// Name to use in the dictionary. Should be unique.
public void AddEventHandler(EventHandler handler, [CallerMemberName]string eventName = null)
where TEventArgs : EventArgs
{
@@ -23,6 +32,11 @@ public void AddEventHandler(EventHandler handler, [Calle
AddEventHandler(eventName, handler.Target, handler.GetMethodInfo());
}
+ ///
+ /// Add an event handler to the manager.
+ ///
+ /// Handler of the event
+ /// Name to use in the dictionary. Should be unique.
public void AddEventHandler(EventHandler handler, [CallerMemberName]string eventName = null)
{
if (IsNullOrEmpty(eventName))
@@ -34,6 +48,12 @@ public void AddEventHandler(EventHandler handler, [CallerMemberName]string event
AddEventHandler(eventName, handler.Target, handler.GetMethodInfo());
}
+ ///
+ /// Handle an event
+ ///
+ /// Sender of the event
+ /// Arguments for the event
+ /// Name of the event.
public void HandleEvent(object sender, object args, string eventName)
{
var toRaise = new List<(object subscriber, MethodInfo handler)>();
@@ -75,6 +95,12 @@ public void HandleEvent(object sender, object args, string eventName)
}
}
+ ///
+ /// Remove an event handler.
+ ///
+ /// Type of the EventArgs
+ /// Handler to remove
+ /// Event name to remove
public void RemoveEventHandler(EventHandler handler, [CallerMemberName]string eventName = null)
where TEventArgs : EventArgs
{
@@ -87,6 +113,11 @@ public void RemoveEventHandler(EventHandler handler, [Ca
RemoveEventHandler(eventName, handler.Target, handler.GetMethodInfo());
}
+ ///
+ /// Remove an event handler.
+ ///
+ /// Handler to remove
+ /// Event name to remove
public void RemoveEventHandler(EventHandler handler, [CallerMemberName]string eventName = null)
{
if (IsNullOrEmpty(eventName))