Skip to content

Commit 52843cb

Browse files
author
Declan Taylor
committed
Moves ViewModelBase and RelayCommand to new project, Infrastructure
1 parent 1634f50 commit 52843cb

File tree

4 files changed

+86
-101
lines changed

4 files changed

+86
-101
lines changed

source/Demos/SuggestBoxTestLib/ViewModels/Base/ViewModelBase.cs

Lines changed: 0 additions & 58 deletions
This file was deleted.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFrameworks>net451;netcoreapp3.0</TargetFrameworks>
5+
</PropertyGroup>
6+
7+
</Project>

source/Demos/SuggestBoxTestLib/ViewModels/Base/RelayCommand.cs renamed to source/Infrastructure/RelayCommand.cs

Lines changed: 24 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
namespace SuggestBoxTestLib.ViewModels.Base
2-
{
3-
using System;
4-
using System.Diagnostics;
5-
using System.Windows.Input;
1+
using System;
2+
using System.Diagnostics;
3+
using System.Windows.Input;
64

5+
namespace Infrastructure
6+
{
77
/// <summary>
88
/// A command whose sole purpose is to
99
/// relay its functionality to other
@@ -13,7 +13,7 @@
1313
///
1414
/// Source: http://www.codeproject.com/Articles/31837/Creating-an-Internationalized-Wizard-in-WPF
1515
/// </summary>
16-
internal class RelayCommand<T> : ICommand
16+
public class RelayCommand<T> : ICommand
1717
{
1818
#region Fields
1919

@@ -51,24 +51,11 @@ public RelayCommand(Action<T> execute, Predicate<T> canExecute)
5151

5252
#region events
5353

54-
/// <summary>
55-
/// Eventhandler to re-evaluate whether this command can execute or not
56-
/// </summary>
57-
public event EventHandler CanExecuteChanged
58-
{
59-
add
60-
{
61-
if (this.mCanExecute != null)
62-
CommandManager.RequerySuggested += value;
63-
}
64-
65-
remove
66-
{
67-
if (this.mCanExecute != null)
68-
CommandManager.RequerySuggested -= value;
69-
}
70-
}
71-
54+
/// <summary>
55+
/// Eventhandler to re-evaluate whether this command can execute or not
56+
/// </summary>
57+
public event EventHandler CanExecuteChanged;
58+
7259
#endregion events
7360

7461
#region methods
@@ -80,10 +67,16 @@ public event EventHandler CanExecuteChanged
8067
/// <returns></returns>
8168
[DebuggerStepThrough]
8269
public bool CanExecute(object parameter)
83-
{
84-
return this.mCanExecute == null ? true : this.mCanExecute((T)parameter);
70+
{
71+
return this.mCanExecute == null || this.mCanExecute((T)parameter);
8572
}
8673

74+
75+
public void RaiseCanExecute()
76+
{
77+
CanExecuteChanged?.Invoke(this, new EventArgs());
78+
}
79+
8780
/// <summary>
8881
/// Execute the command method managed in this class.
8982
/// </summary>
@@ -150,23 +143,11 @@ public RelayCommand(Action execute, Func<bool> canExecute)
150143

151144
#region Events
152145

153-
/// <summary>
154-
/// Eventhandler to re-evaluate whether this command can execute or not
155-
/// </summary>
156-
public event EventHandler CanExecuteChanged
157-
{
158-
add
159-
{
160-
if (this.mCanExecute != null)
161-
CommandManager.RequerySuggested += value;
162-
}
163-
164-
remove
165-
{
166-
if (this.mCanExecute != null)
167-
CommandManager.RequerySuggested -= value;
168-
}
169-
}
146+
/// <summary>
147+
/// Eventhandler to re-evaluate whether this command can execute or not
148+
/// </summary>
149+
public event EventHandler CanExecuteChanged;
150+
170151

171152
#endregion Events
172153

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using System;
2+
using System.ComponentModel;
3+
using System.Linq.Expressions;
4+
using System.Runtime.CompilerServices;
5+
6+
namespace Infrastructure
7+
{
8+
/// <summary>
9+
/// Implements a base class for all viewmodel classes
10+
/// that implements <seealso cref="INotifyPropertyChanged"/> interface for binding.
11+
/// </summary>
12+
public class ViewModelBase : INotifyPropertyChanged
13+
{
14+
/// <summary>
15+
/// Standard implementation of <seealso cref="INotifyPropertyChanged"/>.
16+
/// </summary>
17+
public event PropertyChangedEventHandler PropertyChanged;
18+
19+
/// <summary>
20+
/// Tell bound controls (via WPF binding) to refresh their display.
21+
///
22+
/// Sample call: this.NotifyPropertyChanged(() => this.IsSelected);
23+
/// where 'this' is derived from <seealso cref="ViewModelBase"/>
24+
/// and IsSelected is a property.
25+
/// </summary>
26+
/// <typeparam name="TProperty"></typeparam>
27+
/// <param name="property"></param>
28+
public void NotifyPropertyChanged<TProperty>(Expression<Func<TProperty>> property)
29+
{
30+
var lambda = (LambdaExpression)property;
31+
MemberExpression memberExpression;
32+
33+
if (lambda.Body is UnaryExpression unaryExpression)
34+
{
35+
memberExpression = (MemberExpression)unaryExpression.Operand;
36+
}
37+
else
38+
{
39+
memberExpression = (MemberExpression)lambda.Body;
40+
}
41+
42+
this.NotifyPropertyChanged(memberExpression.Member.Name);
43+
}
44+
45+
/// <summary>
46+
/// Tell bound controls (via WPF binding) to refresh their display.
47+
/// Standard implementation through <seealso cref="INotifyPropertyChanged"/>.
48+
/// </summary>
49+
/// <param name="propertyName"></param>
50+
protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
51+
{
52+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
53+
}
54+
}
55+
}

0 commit comments

Comments
 (0)