├── .gitignore ├── Command ├── RelayCommand.cs └── RelayCommandGeneric.cs ├── GalaSoft.MvvmLight.projitems ├── GalaSoft.MvvmLight.shproj ├── Helpers ├── 1DesignerPlatformLibrary.cs ├── DesignerPlatformLibrary.cs ├── Empty.cs ├── FeatureDetection.cs ├── IExecuteWithObject.cs ├── IExecuteWithObjectAndResult.cs ├── WeakAction.cs ├── WeakActionGeneric.cs ├── WeakFunc.cs └── WeakFuncGeneric.cs ├── ICleanup.cs ├── Messaging ├── GenericMessage.cs ├── IMessenger.cs ├── MessageBase.cs ├── Messenger.cs ├── NotificationMessage.cs ├── NotificationMessageAction.cs ├── NotificationMessageActionGeneric.cs ├── NotificationMessageGeneric.cs ├── NotificationMessageWithCallback.cs ├── PropertyChangedMessage.cs └── PropertyChangedMessageBase.cs ├── ObservableObject.cs ├── README.md ├── ViewModelBase.cs └── Views ├── IDialogService.cs └── INavigationService.cs /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /Command/RelayCommand.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Command.RelayCommand 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | using GalaSoft.MvvmLight.Helpers; 8 | using System; 9 | using System.Windows.Input; 10 | 11 | namespace GalaSoft.MvvmLight.Command 12 | { 13 | /// 14 | /// A command whose sole purpose is to relay its functionality to other 15 | /// objects by invoking delegates. The default return value for the CanExecute 16 | /// method is 'true'. This class does not allow you to accept command parameters in the 17 | /// Execute and CanExecute callback methods. 18 | /// 19 | /// If you are using this class in WPF4.5 or above, you need to use the 20 | /// GalaSoft.MvvmLight.CommandWpf namespace (instead of GalaSoft.MvvmLight.Command). 21 | /// This will enable (or restore) the CommandManager class which handles 22 | /// automatic enabling/disabling of controls based on the CanExecute delegate. 23 | public class RelayCommand : ICommand 24 | { 25 | private readonly WeakAction _execute; 26 | private readonly WeakFunc _canExecute; 27 | 28 | /// 29 | /// Initializes a new instance of the RelayCommand class that 30 | /// can always execute. 31 | /// 32 | /// The execution logic. 33 | /// If the execute argument is null. 34 | public RelayCommand(Action execute) 35 | : this(execute, (Func) null) 36 | { 37 | } 38 | 39 | /// Initializes a new instance of the RelayCommand class. 40 | /// The execution logic. 41 | /// The execution status logic. 42 | /// If the execute argument is null. 43 | public RelayCommand(Action execute, Func canExecute) 44 | { 45 | this._execute = execute != null ? new WeakAction(execute) : throw new ArgumentNullException(nameof (execute)); 46 | if (canExecute == null) 47 | return; 48 | this._canExecute = new WeakFunc(canExecute); 49 | } 50 | 51 | /// 52 | /// Occurs when changes occur that affect whether the command should execute. 53 | /// 54 | public event EventHandler CanExecuteChanged; 55 | 56 | /// 57 | /// Raises the event. 58 | /// 59 | public void RaiseCanExecuteChanged() 60 | { 61 | EventHandler canExecuteChanged = this.CanExecuteChanged; 62 | if (canExecuteChanged == null) 63 | return; 64 | canExecuteChanged((object) this, EventArgs.Empty); 65 | } 66 | 67 | /// 68 | /// Defines the method that determines whether the command can execute in its current state. 69 | /// 70 | /// This parameter will always be ignored. 71 | /// true if this command can be executed; otherwise, false. 72 | public bool CanExecute(object parameter) 73 | { 74 | if (this._canExecute == null) 75 | return true; 76 | return (this._canExecute.IsStatic || this._canExecute.IsAlive) && this._canExecute.Execute(); 77 | } 78 | 79 | /// 80 | /// Defines the method to be called when the command is invoked. 81 | /// 82 | /// This parameter will always be ignored. 83 | public virtual void Execute(object parameter) 84 | { 85 | if (!this.CanExecute(parameter) || this._execute == null || !this._execute.IsStatic && !this._execute.IsAlive) 86 | return; 87 | this._execute.Execute(); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Command/RelayCommandGeneric.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Command.RelayCommand`1 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | using GalaSoft.MvvmLight.Helpers; 8 | using System; 9 | using System.Reflection; 10 | using System.Windows.Input; 11 | 12 | namespace GalaSoft.MvvmLight.Command 13 | { 14 | /// 15 | /// A generic command whose sole purpose is to relay its functionality to other 16 | /// objects by invoking delegates. The default return value for the CanExecute 17 | /// method is 'true'. This class allows you to accept command parameters in the 18 | /// Execute and CanExecute callback methods. 19 | /// 20 | /// The type of the command parameter. 21 | /// If you are using this class in WPF4.5 or above, you need to use the 22 | /// GalaSoft.MvvmLight.CommandWpf namespace (instead of GalaSoft.MvvmLight.Command). 23 | /// This will enable (or restore) the CommandManager class which handles 24 | /// automatic enabling/disabling of controls based on the CanExecute delegate. 25 | public class RelayCommand : ICommand 26 | { 27 | private readonly WeakAction _execute; 28 | private readonly WeakFunc _canExecute; 29 | 30 | /// 31 | /// Initializes a new instance of the RelayCommand class that 32 | /// can always execute. 33 | /// 34 | /// The execution logic. 35 | /// If the execute argument is null. 36 | public RelayCommand(Action execute) 37 | : this(execute, (Func) null) 38 | { 39 | } 40 | 41 | /// Initializes a new instance of the RelayCommand class. 42 | /// The execution logic. 43 | /// The execution status logic. 44 | /// If the execute argument is null. 45 | public RelayCommand(Action execute, Func canExecute) 46 | { 47 | this._execute = execute != null ? new WeakAction(execute) : throw new ArgumentNullException(nameof (execute)); 48 | if (canExecute == null) 49 | return; 50 | this._canExecute = new WeakFunc(canExecute); 51 | } 52 | 53 | /// 54 | /// Occurs when changes occur that affect whether the command should execute. 55 | /// 56 | public event EventHandler CanExecuteChanged; 57 | 58 | /// 59 | /// Raises the event. 60 | /// 61 | public void RaiseCanExecuteChanged() 62 | { 63 | EventHandler canExecuteChanged = this.CanExecuteChanged; 64 | if (canExecuteChanged == null) 65 | return; 66 | canExecuteChanged((object) this, EventArgs.Empty); 67 | } 68 | 69 | /// 70 | /// Defines the method that determines whether the command can execute in its current state. 71 | /// 72 | /// Data used by the command. If the command does not require data 73 | /// to be passed, this object can be set to a null reference 74 | /// true if this command can be executed; otherwise, false. 75 | public bool CanExecute(object parameter) 76 | { 77 | if (this._canExecute == null) 78 | return true; 79 | if (this._canExecute.IsStatic || this._canExecute.IsAlive) 80 | { 81 | if (parameter == null && typeof (T).GetTypeInfo().IsValueType) 82 | return this._canExecute.Execute(default (T)); 83 | if (parameter == null || parameter is T) 84 | return this._canExecute.Execute((T) parameter); 85 | } 86 | return false; 87 | } 88 | 89 | /// 90 | /// Defines the method to be called when the command is invoked. 91 | /// 92 | /// Data used by the command. If the command does not require data 93 | /// to be passed, this object can be set to a null reference 94 | public virtual void Execute(object parameter) 95 | { 96 | object parameter1 = parameter; 97 | if (!this.CanExecute(parameter1) || this._execute == null || !this._execute.IsStatic && !this._execute.IsAlive) 98 | return; 99 | if (parameter1 == null) 100 | { 101 | if (typeof (T).GetTypeInfo().IsValueType) 102 | this._execute.Execute(default (T)); 103 | else 104 | this._execute.Execute((T) parameter1); 105 | } 106 | else 107 | this._execute.Execute((T) parameter1); 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /GalaSoft.MvvmLight.projitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | e0d724f3-a34b-4adf-a582-139c4e4ab3ca 7 | 8 | 9 | GalaSoft.MvvmLight 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /GalaSoft.MvvmLight.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | e0d724f3-a34b-4adf-a582-139c4e4ab3ca 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Helpers/1DesignerPlatformLibrary.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Helpers.DesignerPlatformLibrary 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | namespace GalaSoft.MvvmLight.Helpers 8 | { 9 | internal enum DesignerPlatformLibrary 10 | { 11 | Unknown, 12 | Net, 13 | WinRt, 14 | Silverlight, 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Helpers/DesignerPlatformLibrary.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Helpers.DesignerLibrary 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | using System; 8 | 9 | namespace GalaSoft.MvvmLight.Helpers 10 | { 11 | /// Helper class for platform detection. 12 | internal static class DesignerLibrary 13 | { 14 | private static DesignerPlatformLibrary? _detectedDesignerPlatformLibrary; 15 | 16 | internal static DesignerPlatformLibrary DetectedDesignerLibrary 17 | { 18 | get 19 | { 20 | if (!DesignerLibrary._detectedDesignerPlatformLibrary.HasValue) 21 | DesignerLibrary._detectedDesignerPlatformLibrary = new DesignerPlatformLibrary?(DesignerLibrary.GetCurrentPlatform()); 22 | return DesignerLibrary._detectedDesignerPlatformLibrary.Value; 23 | } 24 | } 25 | 26 | private static DesignerPlatformLibrary GetCurrentPlatform() 27 | { 28 | if (Type.GetType("System.ComponentModel.DesignerProperties, System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e") != null) 29 | return DesignerPlatformLibrary.Silverlight; 30 | if (Type.GetType("System.ComponentModel.DesignerProperties, PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35") != null) 31 | return DesignerPlatformLibrary.Net; 32 | return Type.GetType("Windows.ApplicationModel.DesignMode, Windows, ContentType=WindowsRuntime") != null ? DesignerPlatformLibrary.WinRt : DesignerPlatformLibrary.Unknown; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Helpers/Empty.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Helpers.Empty 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | using System; 8 | using System.Threading.Tasks; 9 | 10 | namespace GalaSoft.MvvmLight.Helpers 11 | { 12 | /// 13 | /// Helper class used when an async method is required, 14 | /// but the context is synchronous. 15 | /// 16 | public static class Empty 17 | { 18 | private static readonly Task ConcreteTask = new Task((Action) (() => {})); 19 | 20 | /// Gets the empty task. 21 | public static Task Task => Empty.ConcreteTask; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Helpers/FeatureDetection.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Helpers.FeatureDetection 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | using System.Reflection; 8 | 9 | namespace GalaSoft.MvvmLight.Helpers 10 | { 11 | /// Helper class for platform and feature detection. 12 | internal static class FeatureDetection 13 | { 14 | private static bool? _isPrivateReflectionSupported; 15 | 16 | public static bool IsPrivateReflectionSupported 17 | { 18 | get 19 | { 20 | if (!FeatureDetection._isPrivateReflectionSupported.HasValue) 21 | FeatureDetection._isPrivateReflectionSupported = new bool?(FeatureDetection.ResolveIsPrivateReflectionSupported()); 22 | return FeatureDetection._isPrivateReflectionSupported.Value; 23 | } 24 | } 25 | 26 | private static bool ResolveIsPrivateReflectionSupported() 27 | { 28 | FeatureDetection.ReflectionDetectionClass reflectionDetectionClass = new FeatureDetection.ReflectionDetectionClass(); 29 | try 30 | { 31 | typeof (FeatureDetection.ReflectionDetectionClass).GetTypeInfo().GetDeclaredMethod("Method").Invoke((object) reflectionDetectionClass, (object[]) null); 32 | } 33 | catch 34 | { 35 | return false; 36 | } 37 | return true; 38 | } 39 | 40 | private class ReflectionDetectionClass 41 | { 42 | private void Method() 43 | { 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Helpers/IExecuteWithObject.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Helpers.IExecuteWithObject 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | namespace GalaSoft.MvvmLight.Helpers 8 | { 9 | /// 10 | /// This interface is meant for the class and can be 11 | /// useful if you store multiple WeakAction{T} instances but don't know in advance 12 | /// what type T represents. 13 | /// 14 | public interface IExecuteWithObject 15 | { 16 | /// The target of the WeakAction. 17 | object Target { get; } 18 | 19 | /// Executes an action. 20 | /// A parameter passed as an object, 21 | /// to be casted to the appropriate type. 22 | void ExecuteWithObject(object parameter); 23 | 24 | /// 25 | /// Deletes all references, which notifies the cleanup method 26 | /// that this entry must be deleted. 27 | /// 28 | void MarkForDeletion(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Helpers/IExecuteWithObjectAndResult.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Helpers.IExecuteWithObjectAndResult 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | namespace GalaSoft.MvvmLight.Helpers 8 | { 9 | /// 10 | /// This interface is meant for the class and can be 11 | /// useful if you store multiple WeakFunc{T} instances but don't know in advance 12 | /// what type T represents. 13 | /// 14 | public interface IExecuteWithObjectAndResult 15 | { 16 | /// Executes a Func and returns the result. 17 | /// A parameter passed as an object, 18 | /// to be casted to the appropriate type. 19 | /// The result of the operation. 20 | object ExecuteWithObject(object parameter); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Helpers/WeakAction.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Helpers.WeakAction 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | using System; 8 | using System.Reflection; 9 | 10 | namespace GalaSoft.MvvmLight.Helpers 11 | { 12 | /// 13 | /// Stores an without causing a hard reference 14 | /// to be created to the Action's owner. The owner can be garbage collected at any time. 15 | /// 16 | public class WeakAction 17 | { 18 | private Action _staticAction; 19 | 20 | /// 21 | /// Gets or sets the corresponding to this WeakAction's 22 | /// method passed in the constructor. 23 | /// 24 | protected MethodInfo Method { get; set; } 25 | 26 | /// 27 | /// Gets the name of the method that this WeakAction represents. 28 | /// 29 | public virtual string MethodName => this._staticAction != null ? this._staticAction.GetMethodInfo().Name : this.Method.Name; 30 | 31 | /// 32 | /// Gets or sets a WeakReference to this WeakAction's action's target. 33 | /// This is not necessarily the same as 34 | /// , for example if the 35 | /// method is anonymous. 36 | /// 37 | protected WeakReference ActionReference { get; set; } 38 | 39 | /// 40 | /// Gets or sets a WeakReference to the target passed when constructing 41 | /// the WeakAction. This is not necessarily the same as 42 | /// , for example if the 43 | /// method is anonymous. 44 | /// 45 | protected WeakReference Reference { get; set; } 46 | 47 | /// 48 | /// Gets a value indicating whether the WeakAction is static or not. 49 | /// 50 | public bool IsStatic => this._staticAction != null; 51 | 52 | /// 53 | /// Initializes an empty instance of the class. 54 | /// 55 | protected WeakAction() 56 | { 57 | } 58 | 59 | /// 60 | /// Initializes a new instance of the class. 61 | /// 62 | /// The action that will be associated to this instance. 63 | public WeakAction(Action action) 64 | : this(action == null ? (object) null : action.Target, action) 65 | { 66 | } 67 | 68 | /// 69 | /// Initializes a new instance of the class. 70 | /// 71 | /// The action's owner. 72 | /// The action that will be associated to this instance. 73 | public WeakAction(object target, Action action) 74 | { 75 | if (action.GetMethodInfo().IsStatic) 76 | { 77 | this._staticAction = action; 78 | if (target == null) 79 | return; 80 | this.Reference = new WeakReference(target); 81 | } 82 | else 83 | { 84 | this.Method = action.GetMethodInfo(); 85 | this.ActionReference = new WeakReference(action.Target); 86 | this.Reference = new WeakReference(target); 87 | } 88 | } 89 | 90 | /// 91 | /// Gets a value indicating whether the Action's owner is still alive, or if it was collected 92 | /// by the Garbage Collector already. 93 | /// 94 | public virtual bool IsAlive 95 | { 96 | get 97 | { 98 | if (this._staticAction == null && this.Reference == null) 99 | return false; 100 | return this._staticAction != null && this.Reference == null || this.Reference.IsAlive; 101 | } 102 | } 103 | 104 | /// 105 | /// Gets the Action's owner. This object is stored as a 106 | /// . 107 | /// 108 | public object Target => this.Reference == null ? (object) null : this.Reference.Target; 109 | 110 | /// The target of the weak reference. 111 | protected object ActionTarget => this.ActionReference == null ? (object) null : this.ActionReference.Target; 112 | 113 | /// 114 | /// Executes the action. This only happens if the action's owner 115 | /// is still alive. 116 | /// 117 | public void Execute() 118 | { 119 | if (this._staticAction != null) 120 | { 121 | this._staticAction(); 122 | } 123 | else 124 | { 125 | object actionTarget = this.ActionTarget; 126 | if (!this.IsAlive || this.Method == null || (this.ActionReference == null || actionTarget == null)) 127 | return; 128 | this.Method.Invoke(actionTarget, (object[]) null); 129 | } 130 | } 131 | 132 | /// Sets the reference that this instance stores to null. 133 | public void MarkForDeletion() 134 | { 135 | this.Reference = (WeakReference) null; 136 | this.ActionReference = (WeakReference) null; 137 | this.Method = (MethodInfo) null; 138 | this._staticAction = (Action) null; 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /Helpers/WeakActionGeneric.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Helpers.WeakAction`1 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | using System; 8 | using System.Reflection; 9 | 10 | namespace GalaSoft.MvvmLight.Helpers 11 | { 12 | /// 13 | /// Stores an Action without causing a hard reference 14 | /// to be created to the Action's owner. The owner can be garbage collected at any time. 15 | /// 16 | /// The type of the Action's parameter. 17 | public class WeakAction : WeakAction, IExecuteWithObject 18 | { 19 | private Action _staticAction; 20 | 21 | /// 22 | /// Gets the name of the method that this WeakAction represents. 23 | /// 24 | public override string MethodName => this._staticAction != null ? this._staticAction.GetMethodInfo().Name : this.Method.Name; 25 | 26 | /// 27 | /// Gets a value indicating whether the Action's owner is still alive, or if it was collected 28 | /// by the Garbage Collector already. 29 | /// 30 | public override bool IsAlive 31 | { 32 | get 33 | { 34 | if (this._staticAction == null && this.Reference == null) 35 | return false; 36 | if (this._staticAction == null) 37 | return this.Reference.IsAlive; 38 | return this.Reference == null || this.Reference.IsAlive; 39 | } 40 | } 41 | 42 | /// Initializes a new instance of the WeakAction class. 43 | /// The action that will be associated to this instance. 44 | public WeakAction(Action action) 45 | : this(action == null ? (object) null : action.Target, action) 46 | { 47 | } 48 | 49 | /// Initializes a new instance of the WeakAction class. 50 | /// The action's owner. 51 | /// The action that will be associated to this instance. 52 | public WeakAction(object target, Action action) 53 | { 54 | if (action.GetMethodInfo().IsStatic) 55 | { 56 | this._staticAction = action; 57 | if (target == null) 58 | return; 59 | this.Reference = new WeakReference(target); 60 | } 61 | else 62 | { 63 | this.Method = action.GetMethodInfo(); 64 | this.ActionReference = new WeakReference(action.Target); 65 | this.Reference = new WeakReference(target); 66 | } 67 | } 68 | 69 | /// 70 | /// Executes the action. This only happens if the action's owner 71 | /// is still alive. The action's parameter is set to default(T). 72 | /// 73 | public new void Execute() => this.Execute(default (T)); 74 | 75 | /// 76 | /// Executes the action. This only happens if the action's owner 77 | /// is still alive. 78 | /// 79 | /// A parameter to be passed to the action. 80 | public void Execute(T parameter) 81 | { 82 | if (this._staticAction != null) 83 | { 84 | this._staticAction(parameter); 85 | } 86 | else 87 | { 88 | object actionTarget = this.ActionTarget; 89 | if (!this.IsAlive || this.Method == null || (this.ActionReference == null || actionTarget == null)) 90 | return; 91 | this.Method.Invoke(actionTarget, new object[1] 92 | { 93 | (object) parameter 94 | }); 95 | } 96 | } 97 | 98 | /// 99 | /// Executes the action with a parameter of type object. This parameter 100 | /// will be casted to T. This method implements 101 | /// and can be useful if you store multiple WeakAction{T} instances but don't know in advance 102 | /// what type T represents. 103 | /// 104 | /// The parameter that will be passed to the action after 105 | /// being casted to T. 106 | public void ExecuteWithObject(object parameter) => this.Execute((T) parameter); 107 | 108 | /// 109 | /// Sets all the actions that this WeakAction contains to null, 110 | /// which is a signal for containing objects that this WeakAction 111 | /// should be deleted. 112 | /// 113 | public new void MarkForDeletion() 114 | { 115 | this._staticAction = (Action) null; 116 | base.MarkForDeletion(); 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /Helpers/WeakFunc.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Helpers.WeakFunc`1 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | using System; 8 | using System.Reflection; 9 | 10 | namespace GalaSoft.MvvmLight.Helpers 11 | { 12 | /// 13 | /// Stores a Func<T> without causing a hard reference 14 | /// to be created to the Func's owner. The owner can be garbage collected at any time. 15 | /// 16 | /// The type of the result of the Func that will be stored 17 | /// by this weak reference. 18 | public class WeakFunc 19 | { 20 | private Func _staticFunc; 21 | 22 | /// 23 | /// Gets or sets the corresponding to this WeakFunc's 24 | /// method passed in the constructor. 25 | /// 26 | protected MethodInfo Method { get; set; } 27 | 28 | /// 29 | /// Get a value indicating whether the WeakFunc is static or not. 30 | /// 31 | public bool IsStatic => this._staticFunc != null; 32 | 33 | /// 34 | /// Gets the name of the method that this WeakFunc represents. 35 | /// 36 | public virtual string MethodName => this._staticFunc != null ? this._staticFunc.GetMethodInfo().Name : this.Method.Name; 37 | 38 | /// 39 | /// Gets or sets a WeakReference to this WeakFunc's action's target. 40 | /// This is not necessarily the same as 41 | /// , for example if the 42 | /// method is anonymous. 43 | /// 44 | protected WeakReference FuncReference { get; set; } 45 | 46 | /// 47 | /// Gets or sets a WeakReference to the target passed when constructing 48 | /// the WeakFunc. This is not necessarily the same as 49 | /// , for example if the 50 | /// method is anonymous. 51 | /// 52 | protected WeakReference Reference { get; set; } 53 | 54 | /// Initializes an empty instance of the WeakFunc class. 55 | protected WeakFunc() 56 | { 57 | } 58 | 59 | /// Initializes a new instance of the WeakFunc class. 60 | /// The Func that will be associated to this instance. 61 | public WeakFunc(Func func) 62 | : this(func == null ? (object) null : func.Target, func) 63 | { 64 | } 65 | 66 | /// Initializes a new instance of the WeakFunc class. 67 | /// The Func's owner. 68 | /// The Func that will be associated to this instance. 69 | public WeakFunc(object target, Func func) 70 | { 71 | if (func.GetMethodInfo().IsStatic) 72 | { 73 | this._staticFunc = func; 74 | if (target == null) 75 | return; 76 | this.Reference = new WeakReference(target); 77 | } 78 | else 79 | { 80 | this.Method = func.GetMethodInfo(); 81 | this.FuncReference = new WeakReference(func.Target); 82 | this.Reference = new WeakReference(target); 83 | } 84 | } 85 | 86 | /// 87 | /// Gets a value indicating whether the Func's owner is still alive, or if it was collected 88 | /// by the Garbage Collector already. 89 | /// 90 | public virtual bool IsAlive 91 | { 92 | get 93 | { 94 | if (this._staticFunc == null && this.Reference == null) 95 | return false; 96 | return this._staticFunc != null && this.Reference == null || this.Reference.IsAlive; 97 | } 98 | } 99 | 100 | /// 101 | /// Gets the Func's owner. This object is stored as a 102 | /// . 103 | /// 104 | public object Target => this.Reference == null ? (object) null : this.Reference.Target; 105 | 106 | /// 107 | /// Gets the owner of the Func that was passed as parameter. 108 | /// This is not necessarily the same as 109 | /// , for example if the 110 | /// method is anonymous. 111 | /// 112 | protected object FuncTarget => this.FuncReference == null ? (object) null : this.FuncReference.Target; 113 | 114 | /// 115 | /// Executes the action. This only happens if the Func's owner 116 | /// is still alive. 117 | /// 118 | /// The result of the Func stored as reference. 119 | public TResult Execute() 120 | { 121 | if (this._staticFunc != null) 122 | return this._staticFunc(); 123 | object funcTarget = this.FuncTarget; 124 | return this.IsAlive && this.Method != null && (this.FuncReference != null && funcTarget != null) ? (TResult) this.Method.Invoke(funcTarget, (object[]) null) : default (TResult); 125 | } 126 | 127 | /// Sets the reference that this instance stores to null. 128 | public void MarkForDeletion() 129 | { 130 | this.Reference = (WeakReference) null; 131 | this.FuncReference = (WeakReference) null; 132 | this.Method = (MethodInfo) null; 133 | this._staticFunc = (Func) null; 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /Helpers/WeakFuncGeneric.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Helpers.WeakFunc`2 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | using System; 8 | using System.Reflection; 9 | 10 | namespace GalaSoft.MvvmLight.Helpers 11 | { 12 | /// 13 | /// Stores an Func without causing a hard reference 14 | /// to be created to the Func's owner. The owner can be garbage collected at any time. 15 | /// 16 | /// The type of the Func's parameter. 17 | /// The type of the Func's return value. 18 | public class WeakFunc : WeakFunc, IExecuteWithObjectAndResult 19 | { 20 | private Func _staticFunc; 21 | 22 | /// 23 | /// Gets or sets the name of the method that this WeakFunc represents. 24 | /// 25 | public override string MethodName => this._staticFunc != null ? this._staticFunc.GetMethodInfo().Name : this.Method.Name; 26 | 27 | /// 28 | /// Gets a value indicating whether the Func's owner is still alive, or if it was collected 29 | /// by the Garbage Collector already. 30 | /// 31 | public override bool IsAlive 32 | { 33 | get 34 | { 35 | if (this._staticFunc == null && this.Reference == null) 36 | return false; 37 | if (this._staticFunc == null) 38 | return this.Reference.IsAlive; 39 | return this.Reference == null || this.Reference.IsAlive; 40 | } 41 | } 42 | 43 | /// Initializes a new instance of the WeakFunc class. 44 | /// The Func that will be associated to this instance. 45 | public WeakFunc(Func func) 46 | : this(func == null ? (object) null : func.Target, func) 47 | { 48 | } 49 | 50 | /// Initializes a new instance of the WeakFunc class. 51 | /// The Func's owner. 52 | /// The Func that will be associated to this instance. 53 | public WeakFunc(object target, Func func) 54 | { 55 | if (func.GetMethodInfo().IsStatic) 56 | { 57 | this._staticFunc = func; 58 | if (target == null) 59 | return; 60 | this.Reference = new WeakReference(target); 61 | } 62 | else 63 | { 64 | this.Method = func.GetMethodInfo(); 65 | this.FuncReference = new WeakReference(func.Target); 66 | this.Reference = new WeakReference(target); 67 | } 68 | } 69 | 70 | /// 71 | /// Executes the Func. This only happens if the Func's owner 72 | /// is still alive. The Func's parameter is set to default(T). 73 | /// 74 | /// The result of the Func stored as reference. 75 | public new TResult Execute() => this.Execute(default (T)); 76 | 77 | /// 78 | /// Executes the Func. This only happens if the Func's owner 79 | /// is still alive. 80 | /// 81 | /// A parameter to be passed to the action. 82 | /// The result of the Func stored as reference. 83 | public TResult Execute(T parameter) 84 | { 85 | if (this._staticFunc != null) 86 | return this._staticFunc(parameter); 87 | object funcTarget = this.FuncTarget; 88 | if (!this.IsAlive || this.Method == null || (this.FuncReference == null || funcTarget == null)) 89 | return default (TResult); 90 | return (TResult) this.Method.Invoke(funcTarget, new object[1] 91 | { 92 | (object) parameter 93 | }); 94 | } 95 | 96 | /// 97 | /// Executes the Func with a parameter of type object. This parameter 98 | /// will be casted to T. This method implements 99 | /// and can be useful if you store multiple WeakFunc{T} instances but don't know in advance 100 | /// what type T represents. 101 | /// 102 | /// The parameter that will be passed to the Func after 103 | /// being casted to T. 104 | /// The result of the execution as object, to be casted to T. 105 | public object ExecuteWithObject(object parameter) => (object) this.Execute((T) parameter); 106 | 107 | /// 108 | /// Sets all the funcs that this WeakFunc contains to null, 109 | /// which is a signal for containing objects that this WeakFunc 110 | /// should be deleted. 111 | /// 112 | public new void MarkForDeletion() 113 | { 114 | this._staticFunc = (Func) null; 115 | base.MarkForDeletion(); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /ICleanup.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.ICleanup 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | namespace GalaSoft.MvvmLight 8 | { 9 | /// 10 | /// Defines a common interface for classes that should be cleaned up, 11 | /// but without the implications that IDisposable presupposes. An instance 12 | /// implementing ICleanup can be cleaned up without being 13 | /// disposed and garbage collected. 14 | /// 15 | public interface ICleanup 16 | { 17 | /// 18 | /// Cleans up the instance, for example by saving its state, 19 | /// removing resources, etc... 20 | /// 21 | void Cleanup(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Messaging/GenericMessage.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Messaging.GenericMessage`1 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | namespace GalaSoft.MvvmLight.Messaging 8 | { 9 | /// Passes a generic value (Content) to a recipient. 10 | /// The type of the Content property. 11 | public class GenericMessage : MessageBase 12 | { 13 | /// 14 | /// Initializes a new instance of the GenericMessage class. 15 | /// 16 | /// The message content. 17 | public GenericMessage(T content) => this.Content = content; 18 | 19 | /// 20 | /// Initializes a new instance of the GenericMessage class. 21 | /// 22 | /// The message's sender. 23 | /// The message content. 24 | public GenericMessage(object sender, T content) 25 | : base(sender) 26 | => this.Content = content; 27 | 28 | /// 29 | /// Initializes a new instance of the GenericMessage class. 30 | /// 31 | /// The message's sender. 32 | /// The message's intended target. This parameter can be used 33 | /// to give an indication as to whom the message was intended for. Of course 34 | /// this is only an indication, amd may be null. 35 | /// The message content. 36 | public GenericMessage(object sender, object target, T content) 37 | : base(sender, target) 38 | => this.Content = content; 39 | 40 | /// Gets or sets the message's content. 41 | public T Content { get; protected set; } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Messaging/IMessenger.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Messaging.IMessenger 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | using System; 8 | 9 | namespace GalaSoft.MvvmLight.Messaging 10 | { 11 | /// 12 | /// The Messenger is a class allowing objects to exchange messages. 13 | /// 14 | public interface IMessenger 15 | { 16 | /// 17 | /// Registers a recipient for a type of message TMessage. The action 18 | /// parameter will be executed when a corresponding message is sent. 19 | /// Registering a recipient does not create a hard reference to it, 20 | /// so if this recipient is deleted, no memory leak is caused. 21 | /// 22 | /// The type of message that the recipient registers 23 | /// for. 24 | /// The recipient that will receive the messages. 25 | /// The action that will be executed when a message 26 | /// of type TMessage is sent. 27 | void Register(object recipient, Action action); 28 | 29 | /// 30 | /// Registers a recipient for a type of message TMessage. 31 | /// The action parameter will be executed when a corresponding 32 | /// message is sent. See the receiveDerivedMessagesToo parameter 33 | /// for details on how messages deriving from TMessage (or, if TMessage is an interface, 34 | /// messages implementing TMessage) can be received too. 35 | /// Registering a recipient does not create a hard reference to it, 36 | /// so if this recipient is deleted, no memory leak is caused. 37 | /// 38 | /// The type of message that the recipient registers 39 | /// for. 40 | /// The recipient that will receive the messages. 41 | /// A token for a messaging channel. If a recipient registers 42 | /// using a token, and a sender sends a message using the same token, then this 43 | /// message will be delivered to the recipient. Other recipients who did not 44 | /// use a token when registering (or who used a different token) will not 45 | /// get the message. Similarly, messages sent without any token, or with a different 46 | /// token, will not be delivered to that recipient. 47 | /// The action that will be executed when a message 48 | /// of type TMessage is sent. 49 | void Register(object recipient, object token, Action action); 50 | 51 | /// 52 | /// Registers a recipient for a type of message TMessage. 53 | /// The action parameter will be executed when a corresponding 54 | /// message is sent. See the receiveDerivedMessagesToo parameter 55 | /// for details on how messages deriving from TMessage (or, if TMessage is an interface, 56 | /// messages implementing TMessage) can be received too. 57 | /// Registering a recipient does not create a hard reference to it, 58 | /// so if this recipient is deleted, no memory leak is caused. 59 | /// 60 | /// The type of message that the recipient registers 61 | /// for. 62 | /// The recipient that will receive the messages. 63 | /// A token for a messaging channel. If a recipient registers 64 | /// using a token, and a sender sends a message using the same token, then this 65 | /// message will be delivered to the recipient. Other recipients who did not 66 | /// use a token when registering (or who used a different token) will not 67 | /// get the message. Similarly, messages sent without any token, or with a different 68 | /// token, will not be delivered to that recipient. 69 | /// If true, message types deriving from 70 | /// TMessage will also be transmitted to the recipient. For example, if a SendOrderMessage 71 | /// and an ExecuteOrderMessage derive from OrderMessage, registering for OrderMessage 72 | /// and setting receiveDerivedMessagesToo to true will send SendOrderMessage 73 | /// and ExecuteOrderMessage to the recipient that registered. 74 | /// Also, if TMessage is an interface, message types implementing TMessage will also be 75 | /// transmitted to the recipient. For example, if a SendOrderMessage 76 | /// and an ExecuteOrderMessage implement IOrderMessage, registering for IOrderMessage 77 | /// and setting receiveDerivedMessagesToo to true will send SendOrderMessage 78 | /// and ExecuteOrderMessage to the recipient that registered. 79 | /// 80 | /// The action that will be executed when a message 81 | /// of type TMessage is sent. 82 | void Register( 83 | object recipient, 84 | object token, 85 | bool receiveDerivedMessagesToo, 86 | Action action); 87 | 88 | /// 89 | /// Registers a recipient for a type of message TMessage. 90 | /// The action parameter will be executed when a corresponding 91 | /// message is sent. See the receiveDerivedMessagesToo parameter 92 | /// for details on how messages deriving from TMessage (or, if TMessage is an interface, 93 | /// messages implementing TMessage) can be received too. 94 | /// Registering a recipient does not create a hard reference to it, 95 | /// so if this recipient is deleted, no memory leak is caused. 96 | /// 97 | /// The type of message that the recipient registers 98 | /// for. 99 | /// The recipient that will receive the messages. 100 | /// If true, message types deriving from 101 | /// TMessage will also be transmitted to the recipient. For example, if a SendOrderMessage 102 | /// and an ExecuteOrderMessage derive from OrderMessage, registering for OrderMessage 103 | /// and setting receiveDerivedMessagesToo to true will send SendOrderMessage 104 | /// and ExecuteOrderMessage to the recipient that registered. 105 | /// Also, if TMessage is an interface, message types implementing TMessage will also be 106 | /// transmitted to the recipient. For example, if a SendOrderMessage 107 | /// and an ExecuteOrderMessage implement IOrderMessage, registering for IOrderMessage 108 | /// and setting receiveDerivedMessagesToo to true will send SendOrderMessage 109 | /// and ExecuteOrderMessage to the recipient that registered. 110 | /// 111 | /// The action that will be executed when a message 112 | /// of type TMessage is sent. 113 | void Register( 114 | object recipient, 115 | bool receiveDerivedMessagesToo, 116 | Action action); 117 | 118 | /// 119 | /// Sends a message to registered recipients. The message will 120 | /// reach all recipients that registered for this message type 121 | /// using one of the Register methods. 122 | /// 123 | /// The type of message that will be sent. 124 | /// The message to send to registered recipients. 125 | void Send(TMessage message); 126 | 127 | /// 128 | /// Sends a message to registered recipients. The message will 129 | /// reach only recipients that registered for this message type 130 | /// using one of the Register methods, and that are 131 | /// of the targetType. 132 | /// 133 | /// The type of message that will be sent. 134 | /// The type of recipients that will receive 135 | /// the message. The message won't be sent to recipients of another type. 136 | /// The message to send to registered recipients. 137 | void Send(TMessage message); 138 | 139 | /// 140 | /// Sends a message to registered recipients. The message will 141 | /// reach only recipients that registered for this message type 142 | /// using one of the Register methods, and that are 143 | /// of the targetType. 144 | /// 145 | /// The type of message that will be sent. 146 | /// The message to send to registered recipients. 147 | /// A token for a messaging channel. If a recipient registers 148 | /// using a token, and a sender sends a message using the same token, then this 149 | /// message will be delivered to the recipient. Other recipients who did not 150 | /// use a token when registering (or who used a different token) will not 151 | /// get the message. Similarly, messages sent without any token, or with a different 152 | /// token, will not be delivered to that recipient. 153 | void Send(TMessage message, object token); 154 | 155 | /// 156 | /// Unregisters a messager recipient completely. After this method 157 | /// is executed, the recipient will not receive any messages anymore. 158 | /// 159 | /// The recipient that must be unregistered. 160 | void Unregister(object recipient); 161 | 162 | /// 163 | /// Unregisters a message recipient for a given type of messages only. 164 | /// After this method is executed, the recipient will not receive messages 165 | /// of type TMessage anymore, but will still receive other message types (if it 166 | /// registered for them previously). 167 | /// 168 | /// The type of messages that the recipient wants 169 | /// to unregister from. 170 | /// The recipient that must be unregistered. 171 | void Unregister(object recipient); 172 | 173 | /// 174 | /// Unregisters a message recipient for a given type of messages only and for a given token. 175 | /// After this method is executed, the recipient will not receive messages 176 | /// of type TMessage anymore with the given token, but will still receive other message types 177 | /// or messages with other tokens (if it registered for them previously). 178 | /// 179 | /// The recipient that must be unregistered. 180 | /// The token for which the recipient must be unregistered. 181 | /// The type of messages that the recipient wants 182 | /// to unregister from. 183 | void Unregister(object recipient, object token); 184 | 185 | /// 186 | /// Unregisters a message recipient for a given type of messages and for 187 | /// a given action. Other message types will still be transmitted to the 188 | /// recipient (if it registered for them previously). Other actions that have 189 | /// been registered for the message type TMessage and for the given recipient (if 190 | /// available) will also remain available. 191 | /// 192 | /// The type of messages that the recipient wants 193 | /// to unregister from. 194 | /// The recipient that must be unregistered. 195 | /// The action that must be unregistered for 196 | /// the recipient and for the message type TMessage. 197 | void Unregister(object recipient, Action action); 198 | 199 | /// 200 | /// Unregisters a message recipient for a given type of messages, for 201 | /// a given action and a given token. Other message types will still be transmitted to the 202 | /// recipient (if it registered for them previously). Other actions that have 203 | /// been registered for the message type TMessage, for the given recipient and other tokens (if 204 | /// available) will also remain available. 205 | /// 206 | /// The type of messages that the recipient wants 207 | /// to unregister from. 208 | /// The recipient that must be unregistered. 209 | /// The token for which the recipient must be unregistered. 210 | /// The action that must be unregistered for 211 | /// the recipient and for the message type TMessage. 212 | void Unregister(object recipient, object token, Action action); 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /Messaging/MessageBase.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Messaging.MessageBase 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | namespace GalaSoft.MvvmLight.Messaging 8 | { 9 | /// 10 | /// Base class for all messages broadcasted by the Messenger. 11 | /// You can create your own message types by extending this class. 12 | /// 13 | public class MessageBase 14 | { 15 | /// Initializes a new instance of the MessageBase class. 16 | public MessageBase() 17 | { 18 | } 19 | 20 | /// Initializes a new instance of the MessageBase class. 21 | /// The message's original sender. 22 | public MessageBase(object sender) => this.Sender = sender; 23 | 24 | /// Initializes a new instance of the MessageBase class. 25 | /// The message's original sender. 26 | /// The message's intended target. This parameter can be used 27 | /// to give an indication as to whom the message was intended for. Of course 28 | /// this is only an indication, amd may be null. 29 | public MessageBase(object sender, object target) 30 | : this(sender) 31 | => this.Target = target; 32 | 33 | /// Gets or sets the message's sender. 34 | public object Sender { get; protected set; } 35 | 36 | /// 37 | /// Gets or sets the message's intended target. This property can be used 38 | /// to give an indication as to whom the message was intended for. Of course 39 | /// this is only an indication, amd may be null. 40 | /// 41 | public object Target { get; protected set; } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Messaging/Messenger.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Messaging.Messenger 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | using GalaSoft.MvvmLight.Helpers; 8 | using System; 9 | using System.Collections.Generic; 10 | using System.Linq; 11 | using System.Reflection; 12 | using System.Threading; 13 | 14 | namespace GalaSoft.MvvmLight.Messaging 15 | { 16 | /// 17 | /// The Messenger is a class allowing objects to exchange messages. 18 | /// 19 | public class Messenger : IMessenger 20 | { 21 | private static readonly object CreationLock = new object(); 22 | private static IMessenger _defaultInstance; 23 | private readonly object _registerLock = new object(); 24 | private Dictionary> _recipientsOfSubclassesAction; 25 | private Dictionary> _recipientsStrictAction; 26 | private readonly SynchronizationContext _context = SynchronizationContext.Current; 27 | private bool _isCleanupRegistered; 28 | 29 | /// 30 | /// Gets the Messenger's default instance, allowing 31 | /// to register and send messages in a static manner. 32 | /// 33 | public static IMessenger Default 34 | { 35 | get 36 | { 37 | if (Messenger._defaultInstance == null) 38 | { 39 | bool lockTaken = false; 40 | object creationLock = null; 41 | try 42 | { 43 | Monitor.Enter(creationLock = Messenger.CreationLock, ref lockTaken); 44 | if (Messenger._defaultInstance == null) 45 | Messenger._defaultInstance = (IMessenger) new Messenger(); 46 | } 47 | finally 48 | { 49 | if (lockTaken) 50 | Monitor.Exit(creationLock); 51 | } 52 | } 53 | return Messenger._defaultInstance; 54 | } 55 | } 56 | 57 | /// 58 | /// Registers a recipient for a type of message TMessage. The action 59 | /// parameter will be executed when a corresponding message is sent. 60 | /// Registering a recipient does not create a hard reference to it, 61 | /// so if this recipient is deleted, no memory leak is caused. 62 | /// 63 | /// The type of message that the recipient registers 64 | /// for. 65 | /// The recipient that will receive the messages. 66 | /// The action that will be executed when a message 67 | /// of type TMessage is sent. 68 | public virtual void Register(object recipient, Action action) => this.Register(recipient, (object) null, false, action); 69 | 70 | /// 71 | /// Registers a recipient for a type of message TMessage. 72 | /// The action parameter will be executed when a corresponding 73 | /// message is sent. See the receiveDerivedMessagesToo parameter 74 | /// for details on how messages deriving from TMessage (or, if TMessage is an interface, 75 | /// messages implementing TMessage) can be received too. 76 | /// Registering a recipient does not create a hard reference to it, 77 | /// so if this recipient is deleted, no memory leak is caused. 78 | /// 79 | /// The type of message that the recipient registers 80 | /// for. 81 | /// The recipient that will receive the messages. 82 | /// If true, message types deriving from 83 | /// TMessage will also be transmitted to the recipient. For example, if a SendOrderMessage 84 | /// and an ExecuteOrderMessage derive from OrderMessage, registering for OrderMessage 85 | /// and setting receiveDerivedMessagesToo to true will send SendOrderMessage 86 | /// and ExecuteOrderMessage to the recipient that registered. 87 | /// Also, if TMessage is an interface, message types implementing TMessage will also be 88 | /// transmitted to the recipient. For example, if a SendOrderMessage 89 | /// and an ExecuteOrderMessage implement IOrderMessage, registering for IOrderMessage 90 | /// and setting receiveDerivedMessagesToo to true will send SendOrderMessage 91 | /// and ExecuteOrderMessage to the recipient that registered. 92 | /// 93 | /// The action that will be executed when a message 94 | /// of type TMessage is sent. 95 | public virtual void Register( 96 | object recipient, 97 | bool receiveDerivedMessagesToo, 98 | Action action) 99 | { 100 | this.Register(recipient, (object) null, receiveDerivedMessagesToo, action); 101 | } 102 | 103 | /// 104 | /// Registers a recipient for a type of message TMessage. 105 | /// The action parameter will be executed when a corresponding 106 | /// message is sent. 107 | /// Registering a recipient does not create a hard reference to it, 108 | /// so if this recipient is deleted, no memory leak is caused. 109 | /// 110 | /// The type of message that the recipient registers 111 | /// for. 112 | /// The recipient that will receive the messages. 113 | /// A token for a messaging channel. If a recipient registers 114 | /// using a token, and a sender sends a message using the same token, then this 115 | /// message will be delivered to the recipient. Other recipients who did not 116 | /// use a token when registering (or who used a different token) will not 117 | /// get the message. Similarly, messages sent without any token, or with a different 118 | /// token, will not be delivered to that recipient. 119 | /// The action that will be executed when a message 120 | /// of type TMessage is sent. 121 | public virtual void Register(object recipient, object token, Action action) => this.Register(recipient, token, false, action); 122 | 123 | /// 124 | /// Registers a recipient for a type of message TMessage. 125 | /// The action parameter will be executed when a corresponding 126 | /// message is sent. See the receiveDerivedMessagesToo parameter 127 | /// for details on how messages deriving from TMessage (or, if TMessage is an interface, 128 | /// messages implementing TMessage) can be received too. 129 | /// Registering a recipient does not create a hard reference to it, 130 | /// so if this recipient is deleted, no memory leak is caused. 131 | /// 132 | /// The type of message that the recipient registers 133 | /// for. 134 | /// The recipient that will receive the messages. 135 | /// A token for a messaging channel. If a recipient registers 136 | /// using a token, and a sender sends a message using the same token, then this 137 | /// message will be delivered to the recipient. Other recipients who did not 138 | /// use a token when registering (or who used a different token) will not 139 | /// get the message. Similarly, messages sent without any token, or with a different 140 | /// token, will not be delivered to that recipient. 141 | /// If true, message types deriving from 142 | /// TMessage will also be transmitted to the recipient. For example, if a SendOrderMessage 143 | /// and an ExecuteOrderMessage derive from OrderMessage, registering for OrderMessage 144 | /// and setting receiveDerivedMessagesToo to true will send SendOrderMessage 145 | /// and ExecuteOrderMessage to the recipient that registered. 146 | /// Also, if TMessage is an interface, message types implementing TMessage will also be 147 | /// transmitted to the recipient. For example, if a SendOrderMessage 148 | /// and an ExecuteOrderMessage implement IOrderMessage, registering for IOrderMessage 149 | /// and setting receiveDerivedMessagesToo to true will send SendOrderMessage 150 | /// and ExecuteOrderMessage to the recipient that registered. 151 | /// 152 | /// The action that will be executed when a message 153 | /// of type TMessage is sent. 154 | public virtual void Register( 155 | object recipient, 156 | object token, 157 | bool receiveDerivedMessagesToo, 158 | Action action) 159 | { 160 | bool lockTaken1 = false; 161 | object registerLock = null; 162 | try 163 | { 164 | Monitor.Enter(registerLock = this._registerLock, ref lockTaken1); 165 | Type key = typeof (TMessage); 166 | Dictionary> dictionary1; 167 | if (receiveDerivedMessagesToo) 168 | { 169 | if (this._recipientsOfSubclassesAction == null) 170 | this._recipientsOfSubclassesAction = new Dictionary>(); 171 | dictionary1 = this._recipientsOfSubclassesAction; 172 | } 173 | else 174 | { 175 | if (this._recipientsStrictAction == null) 176 | this._recipientsStrictAction = new Dictionary>(); 177 | dictionary1 = this._recipientsStrictAction; 178 | } 179 | bool lockTaken2 = false; 180 | Dictionary> dictionary2 = null; 181 | try 182 | { 183 | Monitor.Enter((object) (dictionary2 = dictionary1), ref lockTaken2); 184 | List weakActionAndTokenList; 185 | if (!dictionary1.ContainsKey(key)) 186 | { 187 | weakActionAndTokenList = new List(); 188 | dictionary1.Add(key, weakActionAndTokenList); 189 | } 190 | else 191 | weakActionAndTokenList = dictionary1[key]; 192 | WeakAction weakAction = new WeakAction(recipient, action); 193 | Messenger.WeakActionAndToken weakActionAndToken = new Messenger.WeakActionAndToken() 194 | { 195 | Action = (WeakAction) weakAction, 196 | Token = token 197 | }; 198 | weakActionAndTokenList.Add(weakActionAndToken); 199 | } 200 | finally 201 | { 202 | if (lockTaken2) 203 | Monitor.Exit((object) dictionary2); 204 | } 205 | } 206 | finally 207 | { 208 | if (lockTaken1) 209 | Monitor.Exit(registerLock); 210 | } 211 | this.RequestCleanup(); 212 | } 213 | 214 | /// 215 | /// Sends a message to registered recipients. The message will 216 | /// reach all recipients that registered for this message type 217 | /// using one of the Register methods. 218 | /// 219 | /// The type of message that will be sent. 220 | /// The message to send to registered recipients. 221 | public virtual void Send(TMessage message) => this.SendToTargetOrType(message, (Type) null, (object) null); 222 | 223 | /// 224 | /// Sends a message to registered recipients. The message will 225 | /// reach only recipients that registered for this message type 226 | /// using one of the Register methods, and that are 227 | /// of the targetType. 228 | /// 229 | /// The type of message that will be sent. 230 | /// The type of recipients that will receive 231 | /// the message. The message won't be sent to recipients of another type. 232 | /// The message to send to registered recipients. 233 | public virtual void Send(TMessage message) => this.SendToTargetOrType(message, typeof (TTarget), (object) null); 234 | 235 | /// 236 | /// Sends a message to registered recipients. The message will 237 | /// reach only recipients that registered for this message type 238 | /// using one of the Register methods, and that are 239 | /// of the targetType. 240 | /// 241 | /// The type of message that will be sent. 242 | /// The message to send to registered recipients. 243 | /// A token for a messaging channel. If a recipient registers 244 | /// using a token, and a sender sends a message using the same token, then this 245 | /// message will be delivered to the recipient. Other recipients who did not 246 | /// use a token when registering (or who used a different token) will not 247 | /// get the message. Similarly, messages sent without any token, or with a different 248 | /// token, will not be delivered to that recipient. 249 | public virtual void Send(TMessage message, object token) => this.SendToTargetOrType(message, (Type) null, token); 250 | 251 | /// 252 | /// Unregisters a messager recipient completely. After this method 253 | /// is executed, the recipient will not receive any messages anymore. 254 | /// 255 | /// The recipient that must be unregistered. 256 | public virtual void Unregister(object recipient) 257 | { 258 | Messenger.UnregisterFromLists(recipient, this._recipientsOfSubclassesAction); 259 | Messenger.UnregisterFromLists(recipient, this._recipientsStrictAction); 260 | } 261 | 262 | /// 263 | /// Unregisters a message recipient for a given type of messages only. 264 | /// After this method is executed, the recipient will not receive messages 265 | /// of type TMessage anymore, but will still receive other message types (if it 266 | /// registered for them previously). 267 | /// 268 | /// The recipient that must be unregistered. 269 | /// The type of messages that the recipient wants 270 | /// to unregister from. 271 | public virtual void Unregister(object recipient) => this.Unregister(recipient, (object) null, (Action) null); 272 | 273 | /// 274 | /// Unregisters a message recipient for a given type of messages only and for a given token. 275 | /// After this method is executed, the recipient will not receive messages 276 | /// of type TMessage anymore with the given token, but will still receive other message types 277 | /// or messages with other tokens (if it registered for them previously). 278 | /// 279 | /// The recipient that must be unregistered. 280 | /// The token for which the recipient must be unregistered. 281 | /// The type of messages that the recipient wants 282 | /// to unregister from. 283 | public virtual void Unregister(object recipient, object token) => this.Unregister(recipient, token, (Action) null); 284 | 285 | /// 286 | /// Unregisters a message recipient for a given type of messages and for 287 | /// a given action. Other message types will still be transmitted to the 288 | /// recipient (if it registered for them previously). Other actions that have 289 | /// been registered for the message type TMessage and for the given recipient (if 290 | /// available) will also remain available. 291 | /// 292 | /// The type of messages that the recipient wants 293 | /// to unregister from. 294 | /// The recipient that must be unregistered. 295 | /// The action that must be unregistered for 296 | /// the recipient and for the message type TMessage. 297 | public virtual void Unregister(object recipient, Action action) => this.Unregister(recipient, (object) null, action); 298 | 299 | /// 300 | /// Unregisters a message recipient for a given type of messages, for 301 | /// a given action and a given token. Other message types will still be transmitted to the 302 | /// recipient (if it registered for them previously). Other actions that have 303 | /// been registered for the message type TMessage, for the given recipient and other tokens (if 304 | /// available) will also remain available. 305 | /// 306 | /// The type of messages that the recipient wants 307 | /// to unregister from. 308 | /// The recipient that must be unregistered. 309 | /// The token for which the recipient must be unregistered. 310 | /// The action that must be unregistered for 311 | /// the recipient and for the message type TMessage. 312 | public virtual void Unregister( 313 | object recipient, 314 | object token, 315 | Action action) 316 | { 317 | Messenger.UnregisterFromLists(recipient, token, action, this._recipientsStrictAction); 318 | Messenger.UnregisterFromLists(recipient, token, action, this._recipientsOfSubclassesAction); 319 | this.RequestCleanup(); 320 | } 321 | 322 | /// 323 | /// Provides a way to override the Messenger.Default instance with 324 | /// a custom instance, for example for unit testing purposes. 325 | /// 326 | /// The instance that will be used as Messenger.Default. 327 | public static void OverrideDefault(IMessenger newMessenger) => Messenger._defaultInstance = newMessenger; 328 | 329 | /// 330 | /// Sets the Messenger's default (static) instance to null. 331 | /// 332 | public static void Reset() => Messenger._defaultInstance = (IMessenger) null; 333 | 334 | /// 335 | /// Provides a non-static access to the static method. 336 | /// Sets the Messenger's default (static) instance to null. 337 | /// 338 | public void ResetAll() => Messenger.Reset(); 339 | 340 | private static void CleanupList( 341 | IDictionary> lists) 342 | { 343 | if (lists == null) 344 | return; 345 | bool lockTaken = false; 346 | IDictionary> dictionary = null; 347 | try 348 | { 349 | Monitor.Enter((object) (dictionary = lists), ref lockTaken); 350 | List typeList = new List(); 351 | foreach (KeyValuePair> list in (IEnumerable>>) lists) 352 | { 353 | foreach (Messenger.WeakActionAndToken weakActionAndToken in list.Value.Where((Func) (item => item.Action == null || !item.Action.IsAlive)).ToList()) 354 | list.Value.Remove(weakActionAndToken); 355 | if (list.Value.Count == 0) 356 | typeList.Add(list.Key); 357 | } 358 | foreach (Type key in typeList) 359 | lists.Remove(key); 360 | } 361 | finally 362 | { 363 | if (lockTaken) 364 | Monitor.Exit((object) dictionary); 365 | } 366 | } 367 | 368 | private static void SendToList( 369 | TMessage message, 370 | IEnumerable weakActionsAndTokens, 371 | Type messageTargetType, 372 | object token) 373 | { 374 | if (weakActionsAndTokens == null) 375 | return; 376 | List list = weakActionsAndTokens.ToList(); 377 | foreach (Messenger.WeakActionAndToken weakActionAndToken in list.Take(list.Count()).ToList()) 378 | { 379 | if (weakActionAndToken.Action is IExecuteWithObject action && weakActionAndToken.Action.IsAlive && weakActionAndToken.Action.Target != null && (messageTargetType == null || weakActionAndToken.Action.Target.GetType() == messageTargetType || messageTargetType.GetTypeInfo().IsAssignableFrom(weakActionAndToken.Action.Target.GetType().GetTypeInfo())) && (weakActionAndToken.Token == null && token == null || weakActionAndToken.Token != null && weakActionAndToken.Token.Equals(token))) 380 | action.ExecuteWithObject((object) message); 381 | } 382 | } 383 | 384 | private static void UnregisterFromLists( 385 | object recipient, 386 | Dictionary> lists) 387 | { 388 | if (recipient == null || lists == null || lists.Count == 0) 389 | return; 390 | bool lockTaken = false; 391 | Dictionary> dictionary = null; 392 | try 393 | { 394 | Monitor.Enter((object) (dictionary = lists), ref lockTaken); 395 | foreach (Type key in lists.Keys) 396 | { 397 | foreach (Messenger.WeakActionAndToken weakActionAndToken in lists[key]) 398 | { 399 | IExecuteWithObject action = (IExecuteWithObject) weakActionAndToken.Action; 400 | if (action != null && recipient == action.Target) 401 | action.MarkForDeletion(); 402 | } 403 | } 404 | } 405 | finally 406 | { 407 | if (lockTaken) 408 | Monitor.Exit((object) dictionary); 409 | } 410 | } 411 | 412 | private static void UnregisterFromLists( 413 | object recipient, 414 | object token, 415 | Action action, 416 | Dictionary> lists) 417 | { 418 | Type key = typeof (TMessage); 419 | if (recipient == null || lists == null || (lists.Count == 0 || !lists.ContainsKey(key))) 420 | return; 421 | bool lockTaken = false; 422 | Dictionary> dictionary = null; 423 | try 424 | { 425 | Monitor.Enter((object) (dictionary = lists), ref lockTaken); 426 | foreach (Messenger.WeakActionAndToken weakActionAndToken in lists[key]) 427 | { 428 | if (weakActionAndToken.Action is WeakAction action1 && recipient == action1.Target && (action == null || action.GetMethodInfo().Name == action1.MethodName) && (token == null || token.Equals(weakActionAndToken.Token))) 429 | weakActionAndToken.Action.MarkForDeletion(); 430 | } 431 | } 432 | finally 433 | { 434 | if (lockTaken) 435 | Monitor.Exit((object) dictionary); 436 | } 437 | } 438 | 439 | /// 440 | /// Notifies the Messenger that the lists of recipients should 441 | /// be scanned and cleaned up. 442 | /// Since recipients are stored as , 443 | /// recipients can be garbage collected even though the Messenger keeps 444 | /// them in a list. During the cleanup operation, all "dead" 445 | /// recipients are removed from the lists. Since this operation 446 | /// can take a moment, it is only executed when the application is 447 | /// idle. For this reason, a user of the Messenger class should use 448 | /// instead of forcing one with the 449 | /// method. 450 | /// 451 | public void RequestCleanup() 452 | { 453 | if (this._isCleanupRegistered) 454 | return; 455 | Action cleanupAction = new Action(this.Cleanup); 456 | if (this._context != null) 457 | this._context.Post((SendOrPostCallback) (_ => cleanupAction()), (object) null); 458 | else 459 | cleanupAction(); 460 | this._isCleanupRegistered = true; 461 | } 462 | 463 | /// 464 | /// Scans the recipients' lists for "dead" instances and removes them. 465 | /// Since recipients are stored as , 466 | /// recipients can be garbage collected even though the Messenger keeps 467 | /// them in a list. During the cleanup operation, all "dead" 468 | /// recipients are removed from the lists. Since this operation 469 | /// can take a moment, it is only executed when the application is 470 | /// idle. For this reason, a user of the Messenger class should use 471 | /// instead of forcing one with the 472 | /// method. 473 | /// 474 | public void Cleanup() 475 | { 476 | Messenger.CleanupList((IDictionary>) this._recipientsOfSubclassesAction); 477 | Messenger.CleanupList((IDictionary>) this._recipientsStrictAction); 478 | this._isCleanupRegistered = false; 479 | } 480 | 481 | private void SendToTargetOrType( 482 | TMessage message, 483 | Type messageTargetType, 484 | object token) 485 | { 486 | Type type1 = typeof (TMessage); 487 | if (this._recipientsOfSubclassesAction != null) 488 | { 489 | foreach (Type type2 in this._recipientsOfSubclassesAction.Keys.Take(this._recipientsOfSubclassesAction.Count>>()).ToList()) 490 | { 491 | List weakActionAndTokenList = (List) null; 492 | if (type1 == type2 || type1.GetTypeInfo().IsSubclassOf(type2) || type2.GetTypeInfo().IsAssignableFrom(type1.GetTypeInfo())) 493 | { 494 | bool lockTaken = false; 495 | Dictionary> subclassesAction = null; 496 | try 497 | { 498 | Monitor.Enter((object) (subclassesAction = this._recipientsOfSubclassesAction), ref lockTaken); 499 | weakActionAndTokenList = this._recipientsOfSubclassesAction[type2].Take(this._recipientsOfSubclassesAction[type2].Count()).ToList(); 500 | } 501 | finally 502 | { 503 | if (lockTaken) 504 | Monitor.Exit((object) subclassesAction); 505 | } 506 | } 507 | Messenger.SendToList(message, (IEnumerable) weakActionAndTokenList, messageTargetType, token); 508 | } 509 | } 510 | if (this._recipientsStrictAction != null) 511 | { 512 | List weakActionAndTokenList = (List) null; 513 | bool lockTaken = false; 514 | Dictionary> recipientsStrictAction = null; 515 | try 516 | { 517 | Monitor.Enter((object) (recipientsStrictAction = this._recipientsStrictAction), ref lockTaken); 518 | if (this._recipientsStrictAction.ContainsKey(type1)) 519 | weakActionAndTokenList = this._recipientsStrictAction[type1].Take(this._recipientsStrictAction[type1].Count()).ToList(); 520 | } 521 | finally 522 | { 523 | if (lockTaken) 524 | Monitor.Exit((object) recipientsStrictAction); 525 | } 526 | if (weakActionAndTokenList != null) 527 | Messenger.SendToList(message, (IEnumerable) weakActionAndTokenList, messageTargetType, token); 528 | } 529 | this.RequestCleanup(); 530 | } 531 | 532 | private struct WeakActionAndToken 533 | { 534 | public WeakAction Action; 535 | public object Token; 536 | } 537 | } 538 | } 539 | -------------------------------------------------------------------------------- /Messaging/NotificationMessage.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Messaging.NotificationMessage 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | namespace GalaSoft.MvvmLight.Messaging 8 | { 9 | /// 10 | /// Passes a string message (Notification) to a recipient. 11 | /// Typically, notifications are defined as unique strings in a static class. To define 12 | /// a unique string, you can use Guid.NewGuid().ToString() or any other unique 13 | /// identifier. 14 | /// 15 | public class NotificationMessage : MessageBase 16 | { 17 | /// 18 | /// Initializes a new instance of the NotificationMessage class. 19 | /// 20 | /// A string containing any arbitrary message to be 21 | /// passed to recipient(s) 22 | public NotificationMessage(string notification) => this.Notification = notification; 23 | 24 | /// 25 | /// Initializes a new instance of the NotificationMessage class. 26 | /// 27 | /// The message's sender. 28 | /// A string containing any arbitrary message to be 29 | /// passed to recipient(s) 30 | public NotificationMessage(object sender, string notification) 31 | : base(sender) 32 | => this.Notification = notification; 33 | 34 | /// 35 | /// Initializes a new instance of the NotificationMessage class. 36 | /// 37 | /// The message's sender. 38 | /// The message's intended target. This parameter can be used 39 | /// to give an indication as to whom the message was intended for. Of course 40 | /// this is only an indication, amd may be null. 41 | /// A string containing any arbitrary message to be 42 | /// passed to recipient(s) 43 | public NotificationMessage(object sender, object target, string notification) 44 | : base(sender, target) 45 | => this.Notification = notification; 46 | 47 | /// 48 | /// Gets a string containing any arbitrary message to be 49 | /// passed to recipient(s). 50 | /// 51 | public string Notification { get; private set; } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Messaging/NotificationMessageAction.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Messaging.NotificationMessageAction 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | using System; 8 | 9 | namespace GalaSoft.MvvmLight.Messaging 10 | { 11 | /// 12 | /// Provides a message class with a built-in callback. When the recipient 13 | /// is done processing the message, it can execute the callback to 14 | /// notify the sender that it is done. Use the 15 | /// method to execute the callback. 16 | /// 17 | public class NotificationMessageAction : NotificationMessageWithCallback 18 | { 19 | /// 20 | /// Initializes a new instance of the 21 | /// class. 22 | /// 23 | /// An arbitrary string that will be 24 | /// carried by the message. 25 | /// The callback method that can be executed 26 | /// by the recipient to notify the sender that the message has been 27 | /// processed. 28 | public NotificationMessageAction(string notification, Action callback) 29 | : base(notification, (Delegate) callback) 30 | { 31 | } 32 | 33 | /// 34 | /// Initializes a new instance of the 35 | /// class. 36 | /// 37 | /// The message's sender. 38 | /// An arbitrary string that will be 39 | /// carried by the message. 40 | /// The callback method that can be executed 41 | /// by the recipient to notify the sender that the message has been 42 | /// processed. 43 | public NotificationMessageAction(object sender, string notification, Action callback) 44 | : base(sender, notification, (Delegate) callback) 45 | { 46 | } 47 | 48 | /// 49 | /// Initializes a new instance of the 50 | /// class. 51 | /// 52 | /// The message's sender. 53 | /// The message's intended target. This parameter can be used 54 | /// to give an indication as to whom the message was intended for. Of course 55 | /// this is only an indication, amd may be null. 56 | /// An arbitrary string that will be 57 | /// carried by the message. 58 | /// The callback method that can be executed 59 | /// by the recipient to notify the sender that the message has been 60 | /// processed. 61 | public NotificationMessageAction( 62 | object sender, 63 | object target, 64 | string notification, 65 | Action callback) 66 | : base(sender, target, notification, (Delegate) callback) 67 | { 68 | } 69 | 70 | /// 71 | /// Executes the callback that was provided with the message. 72 | /// 73 | public void Execute() => this.Execute(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Messaging/NotificationMessageActionGeneric.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Messaging.NotificationMessageAction`1 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | using System; 8 | 9 | namespace GalaSoft.MvvmLight.Messaging 10 | { 11 | /// 12 | /// Provides a message class with a built-in callback. When the recipient 13 | /// is done processing the message, it can execute the callback to 14 | /// notify the sender that it is done. Use the 15 | /// method to execute the callback. The callback method has one parameter. 16 | /// . 17 | /// 18 | /// The type of the callback method's 19 | /// only parameter. 20 | public class NotificationMessageAction : NotificationMessageWithCallback 21 | { 22 | /// 23 | /// Initializes a new instance of the 24 | /// class. 25 | /// 26 | /// An arbitrary string that will be 27 | /// carried by the message. 28 | /// The callback method that can be executed 29 | /// by the recipient to notify the sender that the message has been 30 | /// processed. 31 | public NotificationMessageAction(string notification, Action callback) 32 | : base(notification, (Delegate) callback) 33 | { 34 | } 35 | 36 | /// 37 | /// Initializes a new instance of the 38 | /// class. 39 | /// 40 | /// The message's sender. 41 | /// An arbitrary string that will be 42 | /// carried by the message. 43 | /// The callback method that can be executed 44 | /// by the recipient to notify the sender that the message has been 45 | /// processed. 46 | public NotificationMessageAction( 47 | object sender, 48 | string notification, 49 | Action callback) 50 | : base(sender, notification, (Delegate) callback) 51 | { 52 | } 53 | 54 | /// 55 | /// Initializes a new instance of the 56 | /// class. 57 | /// 58 | /// The message's sender. 59 | /// The message's intended target. This parameter can be used 60 | /// to give an indication as to whom the message was intended for. Of course 61 | /// this is only an indication, amd may be null. 62 | /// An arbitrary string that will be 63 | /// carried by the message. 64 | /// The callback method that can be executed 65 | /// by the recipient to notify the sender that the message has been 66 | /// processed. 67 | public NotificationMessageAction( 68 | object sender, 69 | object target, 70 | string notification, 71 | Action callback) 72 | : base(sender, target, notification, (Delegate) callback) 73 | { 74 | } 75 | 76 | /// 77 | /// Executes the callback that was provided with the message. 78 | /// 79 | /// A parameter requested by the message's 80 | /// sender and providing additional information on the recipient's 81 | /// state. 82 | public void Execute(TCallbackParameter parameter) => this.Execute((object) parameter); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Messaging/NotificationMessageGeneric.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Messaging.NotificationMessage`1 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | namespace GalaSoft.MvvmLight.Messaging 8 | { 9 | /// 10 | /// Passes a string message (Notification) and a generic value (Content) to a recipient. 11 | /// 12 | /// The type of the Content property. 13 | public class NotificationMessage : GenericMessage 14 | { 15 | /// 16 | /// Initializes a new instance of the NotificationMessage class. 17 | /// 18 | /// A value to be passed to recipient(s). 19 | /// A string containing any arbitrary message to be 20 | /// passed to recipient(s) 21 | public NotificationMessage(T content, string notification) 22 | : base(content) 23 | => this.Notification = notification; 24 | 25 | /// 26 | /// Initializes a new instance of the NotificationMessage class. 27 | /// 28 | /// The message's sender. 29 | /// A value to be passed to recipient(s). 30 | /// A string containing any arbitrary message to be 31 | /// passed to recipient(s) 32 | public NotificationMessage(object sender, T content, string notification) 33 | : base(sender, content) 34 | => this.Notification = notification; 35 | 36 | /// 37 | /// Initializes a new instance of the NotificationMessage class. 38 | /// 39 | /// The message's sender. 40 | /// The message's intended target. This parameter can be used 41 | /// to give an indication as to whom the message was intended for. Of course 42 | /// this is only an indication, amd may be null. 43 | /// A value to be passed to recipient(s). 44 | /// A string containing any arbitrary message to be 45 | /// passed to recipient(s) 46 | public NotificationMessage(object sender, object target, T content, string notification) 47 | : base(sender, target, content) 48 | => this.Notification = notification; 49 | 50 | /// 51 | /// Gets a string containing any arbitrary message to be 52 | /// passed to recipient(s). 53 | /// 54 | public string Notification { get; private set; } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Messaging/NotificationMessageWithCallback.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Messaging.NotificationMessageWithCallback 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | using System; 8 | 9 | namespace GalaSoft.MvvmLight.Messaging 10 | { 11 | /// 12 | /// Provides a message class with a built-in callback. When the recipient 13 | /// is done processing the message, it can execute the callback to 14 | /// notify the sender that it is done. Use the 15 | /// method to execute the callback. The callback method has one parameter. 16 | /// and 17 | /// . 18 | /// 19 | public class NotificationMessageWithCallback : NotificationMessage 20 | { 21 | private readonly Delegate _callback; 22 | 23 | /// 24 | /// Initializes a new instance of the class. 25 | /// 26 | /// An arbitrary string that will be 27 | /// carried by the message. 28 | /// The callback method that can be executed 29 | /// by the recipient to notify the sender that the message has been 30 | /// processed. 31 | public NotificationMessageWithCallback(string notification, Delegate callback) 32 | : base(notification) 33 | { 34 | NotificationMessageWithCallback.CheckCallback(callback); 35 | this._callback = callback; 36 | } 37 | 38 | /// 39 | /// Initializes a new instance of the class. 40 | /// 41 | /// The message's sender. 42 | /// An arbitrary string that will be 43 | /// carried by the message. 44 | /// The callback method that can be executed 45 | /// by the recipient to notify the sender that the message has been 46 | /// processed. 47 | public NotificationMessageWithCallback(object sender, string notification, Delegate callback) 48 | : base(sender, notification) 49 | { 50 | NotificationMessageWithCallback.CheckCallback(callback); 51 | this._callback = callback; 52 | } 53 | 54 | /// 55 | /// Initializes a new instance of the class. 56 | /// 57 | /// The message's sender. 58 | /// The message's intended target. This parameter can be used 59 | /// to give an indication as to whom the message was intended for. Of course 60 | /// this is only an indication, amd may be null. 61 | /// An arbitrary string that will be 62 | /// carried by the message. 63 | /// The callback method that can be executed 64 | /// by the recipient to notify the sender that the message has been 65 | /// processed. 66 | public NotificationMessageWithCallback( 67 | object sender, 68 | object target, 69 | string notification, 70 | Delegate callback) 71 | : base(sender, target, notification) 72 | { 73 | NotificationMessageWithCallback.CheckCallback(callback); 74 | this._callback = callback; 75 | } 76 | 77 | /// 78 | /// Executes the callback that was provided with the message with an 79 | /// arbitrary number of parameters. 80 | /// 81 | /// A number of parameters that will 82 | /// be passed to the callback method. 83 | /// The object returned by the callback method. 84 | public virtual object Execute(params object[] arguments) => this._callback.DynamicInvoke(arguments); 85 | 86 | private static void CheckCallback(Delegate callback) 87 | { 88 | if ((object) callback == null) 89 | throw new ArgumentNullException(nameof (callback), "Callback may not be null"); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Messaging/PropertyChangedMessage.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Messaging.PropertyChangedMessage`1 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | namespace GalaSoft.MvvmLight.Messaging 8 | { 9 | /// 10 | /// Passes a string property name (PropertyName) and a generic value 11 | /// ( and ) to a recipient. 12 | /// This message type can be used to propagate a PropertyChanged event to 13 | /// a recipient using the messenging system. 14 | /// 15 | /// The type of the OldValue and NewValue property. 16 | public class PropertyChangedMessage : PropertyChangedMessageBase 17 | { 18 | /// 19 | /// Initializes a new instance of the class. 20 | /// 21 | /// The message's sender. 22 | /// The property's value before the change occurred. 23 | /// The property's value after the change occurred. 24 | /// The name of the property that changed. 25 | public PropertyChangedMessage(object sender, T oldValue, T newValue, string propertyName) 26 | : base(sender, propertyName) 27 | { 28 | this.OldValue = oldValue; 29 | this.NewValue = newValue; 30 | } 31 | 32 | /// 33 | /// Initializes a new instance of the class. 34 | /// 35 | /// The property's value before the change occurred. 36 | /// The property's value after the change occurred. 37 | /// The name of the property that changed. 38 | public PropertyChangedMessage(T oldValue, T newValue, string propertyName) 39 | : base(propertyName) 40 | { 41 | this.OldValue = oldValue; 42 | this.NewValue = newValue; 43 | } 44 | 45 | /// 46 | /// Initializes a new instance of the class. 47 | /// 48 | /// The message's sender. 49 | /// The message's intended target. This parameter can be used 50 | /// to give an indication as to whom the message was intended for. Of course 51 | /// this is only an indication, amd may be null. 52 | /// The property's value before the change occurred. 53 | /// The property's value after the change occurred. 54 | /// The name of the property that changed. 55 | public PropertyChangedMessage( 56 | object sender, 57 | object target, 58 | T oldValue, 59 | T newValue, 60 | string propertyName) 61 | : base(sender, target, propertyName) 62 | { 63 | this.OldValue = oldValue; 64 | this.NewValue = newValue; 65 | } 66 | 67 | /// 68 | /// Gets the value that the property has after the change. 69 | /// 70 | public T NewValue { get; private set; } 71 | 72 | /// 73 | /// Gets the value that the property had before the change. 74 | /// 75 | public T OldValue { get; private set; } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Messaging/PropertyChangedMessageBase.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Messaging.PropertyChangedMessageBase 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | namespace GalaSoft.MvvmLight.Messaging 8 | { 9 | /// 10 | /// Basis class for the class. This 11 | /// class allows a recipient to register for all PropertyChangedMessages without 12 | /// having to specify the type T. 13 | /// 14 | public abstract class PropertyChangedMessageBase : MessageBase 15 | { 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | /// The message's sender. 20 | /// The name of the property that changed. 21 | protected PropertyChangedMessageBase(object sender, string propertyName) 22 | : base(sender) 23 | => this.PropertyName = propertyName; 24 | 25 | /// 26 | /// Initializes a new instance of the class. 27 | /// 28 | /// The message's sender. 29 | /// The message's intended target. This parameter can be used 30 | /// to give an indication as to whom the message was intended for. Of course 31 | /// this is only an indication, amd may be null. 32 | /// The name of the property that changed. 33 | protected PropertyChangedMessageBase(object sender, object target, string propertyName) 34 | : base(sender, target) 35 | => this.PropertyName = propertyName; 36 | 37 | /// 38 | /// Initializes a new instance of the class. 39 | /// 40 | /// The name of the property that changed. 41 | protected PropertyChangedMessageBase(string propertyName) => this.PropertyName = propertyName; 42 | 43 | /// Gets or sets the name of the property that changed. 44 | public string PropertyName { get; protected set; } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ObservableObject.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.ObservableObject 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | using System.ComponentModel; 10 | using System.Diagnostics; 11 | using System.Linq.Expressions; 12 | using System.Reflection; 13 | using System.Runtime.CompilerServices; 14 | 15 | namespace GalaSoft.MvvmLight 16 | { 17 | /// 18 | /// A base class for objects of which the properties must be observable. 19 | /// 20 | public class ObservableObject : INotifyPropertyChanged 21 | { 22 | /// Occurs after a property value changes. 23 | public event PropertyChangedEventHandler PropertyChanged; 24 | 25 | /// 26 | /// Provides access to the PropertyChanged event handler to derived classes. 27 | /// 28 | protected PropertyChangedEventHandler PropertyChangedHandler => this.PropertyChanged; 29 | 30 | /// 31 | /// Verifies that a property name exists in this ViewModel. This method 32 | /// can be called before the property is used, for instance before 33 | /// calling RaisePropertyChanged. It avoids errors when a property name 34 | /// is changed but some places are missed. 35 | /// 36 | /// This method is only active in DEBUG mode. 37 | /// The name of the property that will be 38 | /// checked. 39 | [Conditional("DEBUG")] 40 | [DebuggerStepThrough] 41 | public void VerifyPropertyName(string propertyName) 42 | { 43 | Type type = this.GetType(); 44 | if (!string.IsNullOrEmpty(propertyName) && type.GetTypeInfo().GetDeclaredProperty(propertyName) == null) 45 | throw new ArgumentException("Property not found", propertyName); 46 | } 47 | 48 | /// Raises the PropertyChanged event if needed. 49 | /// If the propertyName parameter 50 | /// does not correspond to an existing property on the current class, an 51 | /// exception is thrown in DEBUG configuration only. 52 | /// (optional) The name of the property that 53 | /// changed. 54 | protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null) 55 | { 56 | PropertyChangedEventHandler propertyChanged = this.PropertyChanged; 57 | if (propertyChanged == null) 58 | return; 59 | propertyChanged((object) this, new PropertyChangedEventArgs(propertyName)); 60 | } 61 | 62 | /// Raises the PropertyChanged event if needed. 63 | /// The type of the property that 64 | /// changed. 65 | /// An expression identifying the property 66 | /// that changed. 67 | protected virtual void RaisePropertyChanged(Expression> propertyExpression) 68 | { 69 | PropertyChangedEventHandler propertyChanged = this.PropertyChanged; 70 | if (propertyChanged == null) 71 | return; 72 | string propertyName = ObservableObject.GetPropertyName(propertyExpression); 73 | propertyChanged((object) this, new PropertyChangedEventArgs(propertyName)); 74 | } 75 | 76 | /// Extracts the name of a property from an expression. 77 | /// The type of the property. 78 | /// An expression returning the property's name. 79 | /// The name of the property returned by the expression. 80 | /// If the expression is null. 81 | /// If the expression does not represent a property. 82 | protected static string GetPropertyName(Expression> propertyExpression) 83 | { 84 | if (propertyExpression == null) 85 | throw new ArgumentNullException(nameof (propertyExpression)); 86 | if (!(propertyExpression.Body is MemberExpression body)) 87 | throw new ArgumentException("Invalid argument", nameof (propertyExpression)); 88 | if (!(body.Member is PropertyInfo member)) 89 | throw new ArgumentException("Argument is not a property", nameof (propertyExpression)); 90 | return member.Name; 91 | } 92 | 93 | /// 94 | /// Assigns a new value to the property. Then, raises the 95 | /// PropertyChanged event if needed. 96 | /// 97 | /// The type of the property that 98 | /// changed. 99 | /// An expression identifying the property 100 | /// that changed. 101 | /// The field storing the property's value. 102 | /// The property's value after the change 103 | /// occurred. 104 | /// True if the PropertyChanged event has been raised, 105 | /// false otherwise. The event is not raised if the old 106 | /// value is equal to the new value. 107 | protected bool Set(Expression> propertyExpression, ref T field, T newValue) 108 | { 109 | if (EqualityComparer.Default.Equals(field, newValue)) 110 | return false; 111 | field = newValue; 112 | this.RaisePropertyChanged(propertyExpression); 113 | return true; 114 | } 115 | 116 | /// 117 | /// Assigns a new value to the property. Then, raises the 118 | /// PropertyChanged event if needed. 119 | /// 120 | /// The type of the property that 121 | /// changed. 122 | /// The name of the property that 123 | /// changed. 124 | /// The field storing the property's value. 125 | /// The property's value after the change 126 | /// occurred. 127 | /// True if the PropertyChanged event has been raised, 128 | /// false otherwise. The event is not raised if the old 129 | /// value is equal to the new value. 130 | protected bool Set(string propertyName, ref T field, T newValue) 131 | { 132 | if (EqualityComparer.Default.Equals(field, newValue)) 133 | return false; 134 | field = newValue; 135 | this.RaisePropertyChanged(propertyName); 136 | return true; 137 | } 138 | 139 | /// 140 | /// Assigns a new value to the property. Then, raises the 141 | /// PropertyChanged event if needed. 142 | /// 143 | /// The type of the property that 144 | /// changed. 145 | /// The field storing the property's value. 146 | /// The property's value after the change 147 | /// occurred. 148 | /// (optional) The name of the property that 149 | /// changed. 150 | /// True if the PropertyChanged event has been raised, 151 | /// false otherwise. The event is not raised if the old 152 | /// value is equal to the new value. 153 | protected bool Set(ref T field, T newValue, [CallerMemberName] string propertyName = null) => this.Set(propertyName, ref field, newValue); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GalaSoft.MvvmLight 2 | MvvmLight 框架 3 | 此为共享项目 4 | -------------------------------------------------------------------------------- /ViewModelBase.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.ViewModelBase 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | using GalaSoft.MvvmLight.Helpers; 8 | using GalaSoft.MvvmLight.Messaging; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | using System.Linq; 13 | using System.Linq.Expressions; 14 | using System.Reflection; 15 | using System.Runtime.CompilerServices; 16 | 17 | namespace GalaSoft.MvvmLight 18 | { 19 | /// 20 | /// A base class for the ViewModel classes in the MVVM pattern. 21 | /// 22 | public abstract class ViewModelBase : ObservableObject, ICleanup 23 | { 24 | private static bool? _isInDesignMode; 25 | private IMessenger _messengerInstance; 26 | 27 | /// 28 | /// Initializes a new instance of the ViewModelBase class. 29 | /// 30 | public ViewModelBase() 31 | : this((IMessenger) null) 32 | { 33 | } 34 | 35 | /// 36 | /// Initializes a new instance of the ViewModelBase class. 37 | /// 38 | /// An instance of a 39 | /// used to broadcast messages to other objects. If null, this class 40 | /// will attempt to broadcast using the Messenger's default 41 | /// instance. 42 | public ViewModelBase(IMessenger messenger) => this.MessengerInstance = messenger; 43 | 44 | /// 45 | /// Gets a value indicating whether the control is in design mode 46 | /// (running under Blend or Visual Studio). 47 | /// 48 | public bool IsInDesignMode => ViewModelBase.IsInDesignModeStatic; 49 | 50 | /// 51 | /// Gets a value indicating whether the control is in design mode 52 | /// (running in Blend or Visual Studio). 53 | /// 54 | public static bool IsInDesignModeStatic 55 | { 56 | get 57 | { 58 | if (!ViewModelBase._isInDesignMode.HasValue) 59 | ViewModelBase._isInDesignMode = new bool?(ViewModelBase.IsInDesignModePortable()); 60 | return ViewModelBase._isInDesignMode.Value; 61 | } 62 | } 63 | 64 | private static bool IsInDesignModePortable() 65 | { 66 | switch (DesignerLibrary.DetectedDesignerLibrary) 67 | { 68 | case DesignerPlatformLibrary.Net: 69 | return ViewModelBase.IsInDesignModeNet(); 70 | case DesignerPlatformLibrary.WinRt: 71 | return ViewModelBase.IsInDesignModeMetro(); 72 | case DesignerPlatformLibrary.Silverlight: 73 | bool flag = ViewModelBase.IsInDesignModeSilverlight(); 74 | if (!flag) 75 | flag = ViewModelBase.IsInDesignModeNet(); 76 | return flag; 77 | default: 78 | return false; 79 | } 80 | } 81 | 82 | private static bool IsInDesignModeSilverlight() 83 | { 84 | try 85 | { 86 | Type type = Type.GetType("System.ComponentModel.DesignerProperties, System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"); 87 | if (type == null) 88 | return false; 89 | PropertyInfo declaredProperty = type.GetTypeInfo().GetDeclaredProperty("IsInDesignTool"); 90 | return declaredProperty != null && (bool) declaredProperty.GetValue((object) null, (object[]) null); 91 | } 92 | catch 93 | { 94 | return false; 95 | } 96 | } 97 | 98 | private static bool IsInDesignModeMetro() 99 | { 100 | try 101 | { 102 | return (bool) Type.GetType("Windows.ApplicationModel.DesignMode, Windows, ContentType=WindowsRuntime").GetTypeInfo().GetDeclaredProperty("DesignModeEnabled").GetValue((object) null, (object[]) null); 103 | } 104 | catch 105 | { 106 | return false; 107 | } 108 | } 109 | 110 | private static bool IsInDesignModeNet() 111 | { 112 | try 113 | { 114 | Type type1 = Type.GetType("System.ComponentModel.DesignerProperties, PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"); 115 | if (type1 == null) 116 | return false; 117 | object obj1 = type1.GetTypeInfo().GetDeclaredField("IsInDesignModeProperty").GetValue((object) null); 118 | Type type2 = Type.GetType("System.ComponentModel.DependencyPropertyDescriptor, WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"); 119 | Type type3 = Type.GetType("System.Windows.FrameworkElement, PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"); 120 | if (type2 == null || type3 == null) 121 | return false; 122 | List list = type2.GetTypeInfo().GetDeclaredMethods("FromProperty").ToList(); 123 | if (list == null || list.Count == 0) 124 | return false; 125 | MethodInfo methodInfo = list.FirstOrDefault((Func) (mi => mi.IsPublic && mi.IsStatic && mi.GetParameters().Length == 2)); 126 | if (methodInfo == null) 127 | return false; 128 | object obj2 = methodInfo.Invoke((object) null, new object[2] 129 | { 130 | obj1, 131 | (object) type3 132 | }); 133 | if (obj2 == null) 134 | return false; 135 | PropertyInfo declaredProperty1 = type2.GetTypeInfo().GetDeclaredProperty("Metadata"); 136 | if (declaredProperty1 == null) 137 | return false; 138 | object obj3 = declaredProperty1.GetValue(obj2, (object[]) null); 139 | Type type4 = Type.GetType("System.Windows.PropertyMetadata, WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"); 140 | if (obj3 == null || type4 == null) 141 | return false; 142 | PropertyInfo declaredProperty2 = type4.GetTypeInfo().GetDeclaredProperty("DefaultValue"); 143 | return declaredProperty2 != null && (bool) declaredProperty2.GetValue(obj3, (object[]) null); 144 | } 145 | catch 146 | { 147 | return false; 148 | } 149 | } 150 | 151 | /// 152 | /// Gets or sets an instance of a used to 153 | /// broadcast messages to other objects. If null, this class will 154 | /// attempt to broadcast using the Messenger's default instance. 155 | /// 156 | protected IMessenger MessengerInstance 157 | { 158 | get => this._messengerInstance ?? Messenger.Default; 159 | set => this._messengerInstance = value; 160 | } 161 | 162 | /// 163 | /// Unregisters this instance from the Messenger class. 164 | /// To cleanup additional resources, override this method, clean 165 | /// up and then call base.Cleanup(). 166 | /// 167 | public virtual void Cleanup() => this.MessengerInstance.Unregister((object) this); 168 | 169 | /// 170 | /// Broadcasts a PropertyChangedMessage using either the instance of 171 | /// the Messenger that was passed to this class (if available) 172 | /// or the Messenger's default instance. 173 | /// 174 | /// The type of the property that 175 | /// changed. 176 | /// The value of the property before it 177 | /// changed. 178 | /// The value of the property after it 179 | /// changed. 180 | /// The name of the property that 181 | /// changed. 182 | protected virtual void Broadcast(T oldValue, T newValue, string propertyName) => this.MessengerInstance.Send>(new PropertyChangedMessage((object) this, oldValue, newValue, propertyName)); 183 | 184 | /// 185 | /// Raises the PropertyChanged event if needed, and broadcasts a 186 | /// PropertyChangedMessage using the Messenger instance (or the 187 | /// static default instance if no Messenger instance is available). 188 | /// 189 | /// The type of the property that 190 | /// changed. 191 | /// The name of the property that 192 | /// changed. 193 | /// The property's value before the change 194 | /// occurred. 195 | /// The property's value after the change 196 | /// occurred. 197 | /// If true, a PropertyChangedMessage will 198 | /// be broadcasted. If false, only the event will be raised. 199 | /// If the propertyName parameter 200 | /// does not correspond to an existing property on the current class, an 201 | /// exception is thrown in DEBUG configuration only. 202 | protected virtual void RaisePropertyChanged( 203 | [CallerMemberName] string propertyName = null, 204 | T oldValue = default(T), 205 | T newValue = default(T), 206 | bool broadcast = false) 207 | { 208 | if (string.IsNullOrEmpty(propertyName)) 209 | throw new ArgumentException("This method cannot be called with an empty string", nameof (propertyName)); 210 | this.RaisePropertyChanged(propertyName); 211 | if (!broadcast) 212 | return; 213 | this.Broadcast(oldValue, newValue, propertyName); 214 | } 215 | 216 | /// 217 | /// Raises the PropertyChanged event if needed, and broadcasts a 218 | /// PropertyChangedMessage using the Messenger instance (or the 219 | /// static default instance if no Messenger instance is available). 220 | /// 221 | /// The type of the property that 222 | /// changed. 223 | /// An expression identifying the property 224 | /// that changed. 225 | /// The property's value before the change 226 | /// occurred. 227 | /// The property's value after the change 228 | /// occurred. 229 | /// If true, a PropertyChangedMessage will 230 | /// be broadcasted. If false, only the event will be raised. 231 | protected virtual void RaisePropertyChanged( 232 | Expression> propertyExpression, 233 | T oldValue, 234 | T newValue, 235 | bool broadcast) 236 | { 237 | PropertyChangedEventHandler propertyChangedHandler = this.PropertyChangedHandler; 238 | if (propertyChangedHandler == null && !broadcast) 239 | return; 240 | string propertyName = ObservableObject.GetPropertyName(propertyExpression); 241 | if (propertyChangedHandler != null) 242 | propertyChangedHandler((object) this, new PropertyChangedEventArgs(propertyName)); 243 | if (!broadcast) 244 | return; 245 | this.Broadcast(oldValue, newValue, propertyName); 246 | } 247 | 248 | /// 249 | /// Assigns a new value to the property. Then, raises the 250 | /// PropertyChanged event if needed, and broadcasts a 251 | /// PropertyChangedMessage using the Messenger instance (or the 252 | /// static default instance if no Messenger instance is available). 253 | /// 254 | /// The type of the property that 255 | /// changed. 256 | /// An expression identifying the property 257 | /// that changed. 258 | /// The field storing the property's value. 259 | /// The property's value after the change 260 | /// occurred. 261 | /// If true, a PropertyChangedMessage will 262 | /// be broadcasted. If false, only the event will be raised. 263 | /// True if the PropertyChanged event was raised, false otherwise. 264 | protected bool Set( 265 | Expression> propertyExpression, 266 | ref T field, 267 | T newValue, 268 | bool broadcast) 269 | { 270 | if (EqualityComparer.Default.Equals(field, newValue)) 271 | return false; 272 | T oldValue = field; 273 | field = newValue; 274 | this.RaisePropertyChanged(propertyExpression, oldValue, field, broadcast); 275 | return true; 276 | } 277 | 278 | /// 279 | /// Assigns a new value to the property. Then, raises the 280 | /// PropertyChanged event if needed, and broadcasts a 281 | /// PropertyChangedMessage using the Messenger instance (or the 282 | /// static default instance if no Messenger instance is available). 283 | /// 284 | /// The type of the property that 285 | /// changed. 286 | /// The name of the property that 287 | /// changed. 288 | /// The field storing the property's value. 289 | /// The property's value after the change 290 | /// occurred. 291 | /// If true, a PropertyChangedMessage will 292 | /// be broadcasted. If false, only the event will be raised. 293 | /// True if the PropertyChanged event was raised, false otherwise. 294 | protected bool Set(string propertyName, ref T field, T newValue = default(T), bool broadcast = false) 295 | { 296 | if (EqualityComparer.Default.Equals(field, newValue)) 297 | return false; 298 | T oldValue = field; 299 | field = newValue; 300 | this.RaisePropertyChanged(propertyName, oldValue, field, broadcast); 301 | return true; 302 | } 303 | 304 | /// 305 | /// Assigns a new value to the property. Then, raises the 306 | /// PropertyChanged event if needed, and broadcasts a 307 | /// PropertyChangedMessage using the Messenger instance (or the 308 | /// static default instance if no Messenger instance is available). 309 | /// 310 | /// The type of the property that 311 | /// changed. 312 | /// The field storing the property's value. 313 | /// The property's value after the change 314 | /// occurred. 315 | /// If true, a PropertyChangedMessage will 316 | /// be broadcasted. If false, only the event will be raised. 317 | /// (optional) The name of the property that 318 | /// changed. 319 | /// True if the PropertyChanged event was raised, false otherwise. 320 | protected bool Set(ref T field, T newValue = default(T), bool broadcast = false, [CallerMemberName] string propertyName = null) 321 | { 322 | if (EqualityComparer.Default.Equals(field, newValue)) 323 | return false; 324 | T oldValue = field; 325 | field = newValue; 326 | this.RaisePropertyChanged(propertyName, oldValue, field, broadcast); 327 | return true; 328 | } 329 | } 330 | } 331 | -------------------------------------------------------------------------------- /Views/IDialogService.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Views.IDialogService 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | using System; 8 | using System.Threading.Tasks; 9 | 10 | namespace GalaSoft.MvvmLight.Views 11 | { 12 | /// 13 | /// An interface defining how dialogs should 14 | /// be displayed in various frameworks such as Windows, 15 | /// Windows Phone, Android, iOS etc. 16 | /// 17 | public interface IDialogService 18 | { 19 | /// Displays information about an error. 20 | /// The message to be shown to the user. 21 | /// The title of the dialog box. This may be null. 22 | /// The text shown in the only button 23 | /// in the dialog box. If left null, the text "OK" will be used. 24 | /// A callback that should be executed after 25 | /// the dialog box is closed by the user. 26 | /// A Task allowing this async method to be awaited. 27 | Task ShowError(string message, string title, string buttonText, Action afterHideCallback); 28 | 29 | /// Displays information about an error. 30 | /// The exception of which the message must be shown to the user. 31 | /// The title of the dialog box. This may be null. 32 | /// The text shown in the only button 33 | /// in the dialog box. If left null, the text "OK" will be used. 34 | /// A callback that should be executed after 35 | /// the dialog box is closed by the user. 36 | /// A Task allowing this async method to be awaited. 37 | Task ShowError(Exception error, string title, string buttonText, Action afterHideCallback); 38 | 39 | /// 40 | /// Displays information to the user. The dialog box will have only 41 | /// one button with the text "OK". 42 | /// 43 | /// The message to be shown to the user. 44 | /// The title of the dialog box. This may be null. 45 | /// A Task allowing this async method to be awaited. 46 | Task ShowMessage(string message, string title); 47 | 48 | /// 49 | /// Displays information to the user. The dialog box will have only 50 | /// one button. 51 | /// 52 | /// The message to be shown to the user. 53 | /// The title of the dialog box. This may be null. 54 | /// The text shown in the only button 55 | /// in the dialog box. If left null, the text "OK" will be used. 56 | /// A callback that should be executed after 57 | /// the dialog box is closed by the user. 58 | /// A Task allowing this async method to be awaited. 59 | Task ShowMessage( 60 | string message, 61 | string title, 62 | string buttonText, 63 | Action afterHideCallback); 64 | 65 | /// 66 | /// Displays information to the user. The dialog box will have only 67 | /// one button. 68 | /// 69 | /// The message to be shown to the user. 70 | /// The title of the dialog box. This may be null. 71 | /// The text shown in the "confirm" button 72 | /// in the dialog box. If left null, the text "OK" will be used. 73 | /// The text shown in the "cancel" button 74 | /// in the dialog box. If left null, the text "Cancel" will be used. 75 | /// A callback that should be executed after 76 | /// the dialog box is closed by the user. The callback method will get a boolean 77 | /// parameter indicating if the "confirm" button (true) or the "cancel" button 78 | /// (false) was pressed by the user. 79 | /// A Task allowing this async method to be awaited. The task will return 80 | /// true or false depending on the dialog result. 81 | Task ShowMessage( 82 | string message, 83 | string title, 84 | string buttonConfirmText, 85 | string buttonCancelText, 86 | Action afterHideCallback); 87 | 88 | /// 89 | /// Displays information to the user in a simple dialog box. The dialog box will have only 90 | /// one button with the text "OK". This method should be used for debugging purposes. 91 | /// 92 | /// The message to be shown to the user. 93 | /// The title of the dialog box. This may be null. 94 | /// A Task allowing this async method to be awaited. 95 | Task ShowMessageBox(string message, string title); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Views/INavigationService.cs: -------------------------------------------------------------------------------- 1 | // Decompiled with JetBrains decompiler 2 | // Type: GalaSoft.MvvmLight.Views.INavigationService 3 | // Assembly: GalaSoft.MvvmLight, Version=5.1.1.35049, Culture=neutral, PublicKeyToken=e7570ab207bcb616 4 | // MVID: 5BEDB485-56A9-4001-8E5C-95D46B1034CD 5 | // Assembly location: C:\Users\Asus\OneDrive\Repos\MyDiary\packages\MvvmLightLibs.5.1.1.0\lib\net45\GalaSoft.MvvmLight.dll 6 | 7 | namespace GalaSoft.MvvmLight.Views 8 | { 9 | /// 10 | /// An interface defining how navigation between pages should 11 | /// be performed in various frameworks such as Windows, 12 | /// Windows Phone, Android, iOS etc. 13 | /// 14 | public interface INavigationService 15 | { 16 | /// 17 | /// The key corresponding to the currently displayed page. 18 | /// 19 | string CurrentPageKey { get; } 20 | 21 | /// 22 | /// If possible, instructs the navigation service 23 | /// to discard the current page and display the previous page 24 | /// on the navigation stack. 25 | /// 26 | void GoBack(); 27 | 28 | /// 29 | /// Instructs the navigation service to display a new page 30 | /// corresponding to the given key. Depending on the platforms, 31 | /// the navigation service might have to be configured with a 32 | /// key/page list. 33 | /// 34 | /// The key corresponding to the page 35 | /// that should be displayed. 36 | void NavigateTo(string pageKey); 37 | 38 | /// 39 | /// Instructs the navigation service to display a new page 40 | /// corresponding to the given key, and passes a parameter 41 | /// to the new page. 42 | /// Depending on the platforms, the navigation service might 43 | /// have to be Configure with a key/page list. 44 | /// 45 | /// The key corresponding to the page 46 | /// that should be displayed. 47 | /// The parameter that should be passed 48 | /// to the new page. 49 | void NavigateTo(string pageKey, object parameter); 50 | } 51 | } 52 | --------------------------------------------------------------------------------