// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #pragma warning disable SA1512 // Original file header: // **************************************************************************** // // Copyright © GalaSoft Laurent Bugnion 2009-2016 // // **************************************************************************** // Laurent Bugnion // laurent@galasoft.ch // 22.4.2009 // GalaSoft.MvvmLight // http://www.mvvmlight.net // // See license.txt in this project or http://www.galasoft.ch/license_MIT.txt // // BL0014 // **************************************************************************** using System.Runtime.CompilerServices; using Microsoft.Toolkit.Mvvm.DependencyInjection; using Microsoft.Toolkit.Mvvm.Messaging; using Microsoft.Toolkit.Mvvm.Messaging.Messages; namespace Microsoft.Toolkit.Mvvm.ComponentModel { /// /// A base class for viewmodels. /// public abstract class ViewModelBase : ObservableObject { /// /// Initializes a new instance of the class. /// /// /// This constructor will produce an instance that will use the /// and services to perform operations. /// protected ViewModelBase() : this(Messaging.Messenger.Default, DependencyInjection.Ioc.Default) { } /// /// Initializes a new instance of the class. /// /// The instance to use to send messages. protected ViewModelBase(IMessenger messenger) : this(messenger, DependencyInjection.Ioc.Default) { } /// /// Initializes a new instance of the class. /// /// The optional instance to use to retrieve services. protected ViewModelBase(IIoc ioc) : this(Messaging.Messenger.Default, ioc) { } /// /// Initializes a new instance of the class. /// /// The instance to use to send messages. /// The optional instance to use to retrieve services. protected ViewModelBase(IMessenger messenger, IIoc ioc) { Messenger = messenger; Ioc = ioc; } /// /// Gets the instance in use. /// protected IMessenger Messenger { get; } /// /// Gets the instance in use. /// protected IIoc Ioc { get; } private bool isActive; /// /// Gets or sets a value indicating whether the current view model is currently active. /// public bool IsActive { get => this.isActive; set { if (Set(ref this.isActive, value)) { if (value) { OnActivate(); } else { OnDeactivate(); } } } } /// /// Raised whenever the property is set to . /// Use this method to register to messages and do other initialization for this instance. /// protected virtual void OnActivate() { } /// /// Raised whenever the property is set to . /// Use this method to unregister from messages and do general cleanup for this instance. /// /// The base implementation unregisters all messages for this recipient (with no token). protected virtual void OnDeactivate() { Messenger.Unregister(this); } /// /// Broadcasts a with the specified /// parameters, without using any particular token (so using the default channel). /// /// The type of the property that changed. /// The value of the property before it changed. /// The value of the property after it changed. /// The name of the property that changed. /// /// You should override this method if you wish to customize the channel being /// used to send the message (eg. if you need to use a specific token for the channel). /// protected virtual void Broadcast(T oldValue, T newValue, string propertyName) { var message = new PropertyChangedMessage(this, propertyName, oldValue, newValue); Messenger.Send(message); } /// /// Compares the current and new values for a given property. If the value has changed, /// raises the event, updates the property with /// the new value, then raises the event. /// /// The type of the property that changed. /// The field storing the property's value. /// The property's value after the change occurred. /// If , will also be invoked. /// (optional) The name of the property that changed. /// if the property was changed, otherwise. /// /// This method is just like , just with the addition /// of the parameter. As such, following the behavior of the base method, the /// and events /// are not raised if the current and new value for the target property are the same. /// protected bool Set(ref T field, T newValue, bool broadcast, [CallerMemberName] string propertyName = null!) { if (!broadcast) { return Set(ref field, newValue, propertyName); } T oldValue = field; if (Set(ref field, newValue, propertyName)) { Broadcast(oldValue, newValue, propertyName); return true; } return false; } } }