edit
This commit is contained in:
152
XLAB2/MvvmInfrastructure.cs
Normal file
152
XLAB2/MvvmInfrastructure.cs
Normal file
@@ -0,0 +1,152 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace XLAB2
|
||||
{
|
||||
public abstract class ObservableObject : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
|
||||
{
|
||||
if (Equals(field, value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
field = value;
|
||||
OnPropertyChanged(propertyName);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
var handler = PropertyChanged;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class RelayCommand : ICommand
|
||||
{
|
||||
private readonly Action<object> _execute;
|
||||
private readonly Predicate<object> _canExecute;
|
||||
|
||||
public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
|
||||
{
|
||||
if (execute == null)
|
||||
{
|
||||
throw new ArgumentNullException("execute");
|
||||
}
|
||||
|
||||
_execute = execute;
|
||||
_canExecute = canExecute;
|
||||
}
|
||||
|
||||
public event EventHandler CanExecuteChanged;
|
||||
|
||||
public bool CanExecute(object parameter)
|
||||
{
|
||||
return _canExecute == null || _canExecute(parameter);
|
||||
}
|
||||
|
||||
public void Execute(object parameter)
|
||||
{
|
||||
_execute(parameter);
|
||||
}
|
||||
|
||||
public void RaiseCanExecuteChanged()
|
||||
{
|
||||
var handler = CanExecuteChanged;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class AsyncRelayCommand : ICommand
|
||||
{
|
||||
private readonly Func<object, Task> _executeAsync;
|
||||
private readonly Predicate<object> _canExecute;
|
||||
private bool _isExecuting;
|
||||
|
||||
public AsyncRelayCommand(Func<Task> executeAsync, Func<bool> canExecute = null)
|
||||
: this(
|
||||
delegate { return executeAsync(); },
|
||||
canExecute == null ? null : new Predicate<object>(delegate { return canExecute(); }))
|
||||
{
|
||||
}
|
||||
|
||||
public AsyncRelayCommand(Func<object, Task> executeAsync, Predicate<object> canExecute = null)
|
||||
{
|
||||
if (executeAsync == null)
|
||||
{
|
||||
throw new ArgumentNullException("executeAsync");
|
||||
}
|
||||
|
||||
_executeAsync = executeAsync;
|
||||
_canExecute = canExecute;
|
||||
}
|
||||
|
||||
public event EventHandler CanExecuteChanged;
|
||||
|
||||
public bool IsExecuting
|
||||
{
|
||||
get { return _isExecuting; }
|
||||
private set
|
||||
{
|
||||
if (_isExecuting == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_isExecuting = value;
|
||||
RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanExecute(object parameter)
|
||||
{
|
||||
return !IsExecuting
|
||||
&& (_canExecute == null || _canExecute(parameter));
|
||||
}
|
||||
|
||||
public async void Execute(object parameter)
|
||||
{
|
||||
await ExecuteAsync(parameter);
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync(object parameter = null)
|
||||
{
|
||||
if (!CanExecute(parameter))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
IsExecuting = true;
|
||||
await _executeAsync(parameter);
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsExecuting = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void RaiseCanExecuteChanged()
|
||||
{
|
||||
var handler = CanExecuteChanged;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user