Dreamine.ViewModels Ver.1.0.2
Loading...
Searching...
No Matches
RelayCommand.cs
Go to the documentation of this file.
1using System;
2using System.Threading;
3using System.Windows.Input;
4
6{
11 public sealed class RelayCommand : ICommand
12 {
13 private readonly Action _execute;
14 private readonly Func<bool>? _canExecute;
15
16 private readonly SynchronizationContext? _syncContext;
17
23 public RelayCommand(Action execute, Func<bool>? canExecute = null)
24 {
26 _execute = execute ?? throw new ArgumentNullException(nameof(execute));
27 _canExecute = canExecute;
28
30 _syncContext = SynchronizationContext.Current;
31 }
32
38 public bool CanExecute(object? parameter)
39 {
41 return _canExecute?.Invoke() ?? true;
42 }
43
48 public void Execute(object? parameter)
49 {
50 _execute();
51 }
52
56 public event EventHandler? CanExecuteChanged;
57
63 {
65 var handler = CanExecuteChanged;
66 if (handler is null)
67 return;
68
70 if (_syncContext != null && !ReferenceEquals(SynchronizationContext.Current, _syncContext))
71 {
72 _syncContext.Post(static state =>
73 {
75 var tuple = ((RelayCommand cmd, EventHandler evt))state!;
76 tuple.evt.Invoke(tuple.cmd, EventArgs.Empty);
77 }, (this, handler));
78
79 return;
80 }
81
83 handler.Invoke(this, EventArgs.Empty);
84 }
85 }
86
91 public sealed class RelayCommand<T> : ICommand
92 {
93 private readonly Action<T> _execute;
94 private readonly Func<T, bool>? _canExecute;
95
96 private readonly SynchronizationContext? _syncContext;
97
103 public RelayCommand(Action<T> execute, Func<T, bool>? canExecute = null)
104 {
106 _execute = execute ?? throw new ArgumentNullException(nameof(execute));
107 _canExecute = canExecute;
108
110 _syncContext = SynchronizationContext.Current;
111 }
112
118 public bool CanExecute(object? parameter)
119 {
121 if (_canExecute is null)
122 return true;
123
125 if (!TryGetParameter(parameter, out var value))
126 return false;
127
128 return _canExecute.Invoke(value);
129 }
130
135 public void Execute(object? parameter)
136 {
138 if (!TryGetParameter(parameter, out var value))
139 throw new ArgumentException($"Command parameter is not assignable to {typeof(T).FullName}.", nameof(parameter));
140
141 _execute(value);
142 }
143
148 public event EventHandler? CanExecuteChanged;
149
155 {
157 var handler = CanExecuteChanged;
158 if (handler is null)
159 return;
160
162 if (_syncContext != null && !ReferenceEquals(SynchronizationContext.Current, _syncContext))
163 {
164 _syncContext.Post(static state =>
165 {
167 var tuple = ((RelayCommand<T> cmd, EventHandler evt))state!;
168 tuple.evt.Invoke(tuple.cmd, EventArgs.Empty);
169 }, (this, handler));
170
171 return;
172 }
173
174 handler.Invoke(this, EventArgs.Empty);
175 }
176
183 private static bool TryGetParameter(object? parameter, out T value)
184 {
186 if (parameter is null)
187 {
189 if (default(T) is null)
190 {
191 value = default!;
192 return true;
193 }
194
196 value = default!;
197 return false;
198 }
199
201 if (parameter is T t)
202 {
203 value = t;
204 return true;
205 }
206
208 value = default!;
209 return false;
210 }
211 }
212}
bool CanExecute(object? parameter)
명령이 현재 실행 가능한지를 결정합니다.
void RaiseCanExecuteChanged()
CanExecute 상태를 수동으로 갱신합니다. UI 스레드가 아닌 스레드에서 호출되더라도 UI 스레드로 안전하게 마샬링합니다.
static bool TryGetParameter(object? parameter, out T value)
ICommand parameter를 T 로 안전하게 변환합니다.
readonly? SynchronizationContext _syncContext
readonly? Func< T, bool > _canExecute
void Execute(object? parameter)
명령을 실행합니다.
EventHandler? CanExecuteChanged
명령의 실행 가능 상태가 변경되었음을 알리는 이벤트입니다. UI 바인딩 요소는 이 이벤트를 통해 CanExecute 상태를 다시 평가합니다.
RelayCommand(Action< T > execute, Func< T, bool >? canExecute=null)
RelayCommand 생성자
EventHandler? CanExecuteChanged
명령의 실행 가능 상태가 변경될 때 발생하는 이벤트입니다.
void RaiseCanExecuteChanged()
CanExecute 상태를 수동으로 갱신합니다. UI 스레드가 아닌 스레드에서 호출되더라도 UI 스레드로 안전하게 마샬링합니다.
readonly? Func< bool > _canExecute
void Execute(object? parameter)
명령을 실행합니다.
readonly? SynchronizationContext _syncContext
bool CanExecute(object? parameter)
현재 명령이 실행 가능한지를 나타냅니다.
RelayCommand(Action execute, Func< bool >? canExecute=null)
RelayCommand 생성자