Implementing ViewModelBase and RelayCommand
Before implementing your view models, you must create two classes which will be used by them - ViewModelBase and RelayCommand.
Implementing ViewModelBase
This is the base class for all view models. It implements INotifyPropertyChanged and also takes as a type argument the interface of the view which will be associated with the view model.
public class ViewModelBase<ViewType> : INotifyPropertyChanged
where ViewType : IView
{
public event PropertyChangedEventHandler PropertyChanged;
private readonly ViewType view;
public ViewType View
{
get
{
return this.view;
}
}
public ViewModelBase(ViewType view)
{
this.view = view;
this.View.DataContext = this;
}
public void RaisePropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Public Class ViewModelBase(Of ViewType As IView)
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler _
Implements INotifyPropertyChanged.PropertyChanged
Private ReadOnly _view As ViewType
Public Sub New(ByRef view As ViewType)
Me._view = view
Me.View.DataContext = Me
End Sub
Public ReadOnly Property View As ViewType
Get
Return Me._view
End Get
End Property
Public Sub RaisePropertyChanged(ByVal propertyName As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
Implementing RelayCommand
ReplayCommand implements the ICommand interface. Its instances are command objects through which the view can call methods. As their names suggest, methodToExecute is the actual method of the command, and canExecuteEvaluator is what decides if it is possible to execute the command.
public class RelayCommand : ICommand
{
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
private Action methodToExecute;
private Func<bool> canExecuteEvaluator;
public RelayCommand(Action methodToExecute, Func<bool> canExecuteEvaluator)
{
this.methodToExecute = methodToExecute;
this.canExecuteEvaluator = canExecuteEvaluator;
}
public RelayCommand(Action methodToExecute)
: this(methodToExecute, null)
{
}
public bool CanExecute(object parameter)
{
if (this.canExecuteEvaluator == null)
{
return true;
}
else
{
bool result = this.canExecuteEvaluator.Invoke();
return result;
}
}
public void Execute(object parameter)
{
this.methodToExecute.Invoke();
}
}
Public Class RelayCommand
Implements ICommand
Public Custom Event CanExecuteChanged As EventHandler Implements ICommand.CanExecuteChanged
AddHandler(value As EventHandler)
If IsNothing(Me._canExecuteEvaluator) = False Then
AddHandler CommandManager.RequerySuggested, value
End If
End AddHandler
RemoveHandler(value As EventHandler)
If IsNothing(Me._canExecuteEvaluator) = False Then
AddHandler CommandManager.RequerySuggested, value
End If
End RemoveHandler
RaiseEvent(sender As Object, e As EventArgs)
End RaiseEvent
End Event
Private _methodToExecute As Action
Private _canExecuteEvaluator As Func(Of Boolean)
Public Sub New(ByRef methodToExecute As Action, ByRef canExecuteEvaluator As Func(Of Boolean))
Me._methodToExecute = methodToExecute
Me._canExecuteEvaluator = canExecuteEvaluator
End Sub
Public Sub New(ByRef methodToExecute As Action)
Me.New(methodToExecute, Nothing)
End Sub
Public Function CanExecute(parameter As Object) As Boolean Implements ICommand.CanExecute
If IsNothing(Me._canExecuteEvaluator) Then
Return True
Else
Dim result As Boolean = Me._canExecuteEvaluator.Invoke()
Return result
End If
End Function
Public Sub Execute(parameter As Object) Implements ICommand.Execute
Me._methodToExecute.Invoke()
End Sub
End Class