Skip to content

Instantly share code, notes, and snippets.

@DavidRogersDev
Last active August 29, 2015 13:57
Show Gist options
  • Save DavidRogersDev/9360531 to your computer and use it in GitHub Desktop.
Save DavidRogersDev/9360531 to your computer and use it in GitHub Desktop.
Base ViewModel - This sample base ViewModel class includes the various bits and pieces which all Viewmodels can leverage. It inherits from MVVMLight's ViewModelBase class.
using System;
using System.Linq.Expressions;
using System.Windows.Input;
using CameraDownload.Shared;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using NLog;
namespace CameraDownload.ViewModels
{
/// <summary>
/// This is the top of the ViewModel heirarchy, apart from the ViewModelBase of the MVVM Light Toolkit. It co
/// </summary>
public class CameraDownloadWindowViewModel : ViewModelBase
{
#region Private and Protected Fields
protected string cameraIdCode;
protected bool cameraIdCodeEnabled;
private RelayCommand _closeCommand;
private string confirmMessage;
private bool isBusy;
private bool isValid;
private bool loadingError;
protected string locationNumber;
protected bool locationNumberEnabled;
protected string operatorNumber;
protected bool operatorNumberEnabled;
protected static Logger exceptionLogger = LogManager.GetCurrentClassLogger();
#endregion
/// <summary>
/// Constructor
/// </summary>
public CameraDownloadWindowViewModel()
{
this.isValid = true;
}
#region Properties
public string CameraIdCode
{
get { return cameraIdCode; }
set
{
cameraIdCode = value;
RaisePropertyChanged(() => CameraIdCode);
}
}
public bool CameraIdCodeEnabled
{
get { return cameraIdCodeEnabled; }
set
{
cameraIdCodeEnabled = value;
RaisePropertyChanged(() => CameraIdCodeEnabled);
}
}
public bool IsValid
{
get { return isValid; }
set { isValid = value; }
}
public string LocationNumber
{
get { return locationNumber; }
set
{
locationNumber = value;
RaisePropertyChanged(() =>LocationNumber);
}
}
public bool LocationNumberEnabled
{
get { return locationNumberEnabled; }
set
{
locationNumberEnabled = value;
RaisePropertyChanged(() => LocationNumberEnabled);
}
}
public string OperatorNumber
{
get { return operatorNumber; }
set
{
this.operatorNumber = value;
RaisePropertyChanged(() => OperatorNumber);
}
}
public bool OperatorNumberEnabled
{
get { return this.operatorNumberEnabled; }
set
{
this.operatorNumberEnabled = value;
RaisePropertyChanged(() => OperatorNumberEnabled);
}
}
public string ConfirmMessage
{
get { return confirmMessage; }
set { confirmMessage = value; }
}
public bool LoadingError
{
get { return loadingError; }
set { loadingError = value; }
}
/// <summary>
/// This property is used to show/hide cursors as applicable. It is used with a CursorDisplayConverter
/// and bound to the Cursor property of the relevant control in XAML.
/// </summary>
public bool IsBusy
{
get { return this.isBusy; }
set
{
this.isBusy = value;
RaisePropertyChanged(() => IsBusy);
}
}
#endregion
/// <summary>
/// This delegate is hooked up whenever a new View is loaded.
/// </summary>
public event Action RequestClose;
/// <summary>
/// Returns the command that, when invoked, attempts to remove this View from the user interface.
/// </summary>
public ICommand CloseCommand
{
get
{
if (_closeCommand == null)
_closeCommand = new RelayCommand(() => this.OnRequestClose());
return _closeCommand;
}
}
/// <summary>
/// This method is loaded as the callback that executes when the CloseCommand is executed. It raises the
/// RequestClose event that is hooked up when the View is loaded.
/// </summary>
private void OnRequestClose()
{
Action handler = this.RequestClose;
if (handler != null)
handler();
}
/// <summary>
/// This overload is what enables us to use lambda expressions in the RaisePropertyChanged method used in the setter Properties in the ViewModels
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="propertyExpresssion"></param>
protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpresssion)
{
try
{
string propertyName = this.GetPropertyName(propertyExpresssion);
base.RaisePropertyChanged(propertyName);
}
catch(NotImplementedException notImplementedException)
{
exceptionLogger.LogException(LogLevel.Error, UIConstants.UnkownProperty, notImplementedException);
}
catch(Exception exception)
{
exceptionLogger.LogException(LogLevel.Error, UIConstants.UnkownProperty, exception);
}
}
/// <summary>
/// This method gives us lambda-goodness in our properties.
/// </summary>
/// <typeparam name="T">The type of the Property which utilises this method.</typeparam>
/// <param name="expression">The lambda expression.</param>
/// <returns>The string value which is the name of the Property that is using the lambda expression.</returns>
protected string GetPropertyName<T>(Expression<Func<T>> expression)
{
var memberExpression = expression.Body as MemberExpression;
if (memberExpression == null)
{
var unaryExpression = expression.Body as UnaryExpression;
if (unaryExpression == null)
{
throw new NotImplementedException();
}
memberExpression = unaryExpression.Operand as MemberExpression;
if (memberExpression == null)
{
throw new NotImplementedException();
}
}
return memberExpression.Member.Name;
}
public override void Cleanup()
{
base.Cleanup();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment