// 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;
}
}
}