Last active
August 29, 2015 13:57
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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