From 99c2a93109c170a27e87565bfc46871644966750 Mon Sep 17 00:00:00 2001 From: James Montemagno Date: Thu, 12 Sep 2019 14:49:16 -0700 Subject: [PATCH] Fill in comments. --- .gitignore | 1 + MvvmHelpers/Commands/AsyncCommand.cs | 44 ++++++++++++++++++++++++++++ MvvmHelpers/Commands/Command.cs | 42 ++++++++++++++++++++++++++ MvvmHelpers/MvvmHelpers.csproj | 16 ++++++++-- MvvmHelpers/Utils.cs | 6 ++++ MvvmHelpers/WeakEventManager.cs | 31 ++++++++++++++++++++ 6 files changed, 138 insertions(+), 2 deletions(-) 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))