更新 SimpleObservable

This commit is contained in:
Hakoyu 2023-09-06 17:22:58 +08:00
parent 41fd4bf738
commit 4f1c92c82b
9 changed files with 77 additions and 66 deletions

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -12,26 +13,8 @@ namespace HKW.HKWViewModels.SimpleObservable;
/// </summary> /// </summary>
public class ObservableCommand : ICommand public class ObservableCommand : ICommand
{ {
/// <summary>
/// 执行的方法
/// </summary>
public Action? ExecuteAction { get; set; }
/// <summary>
/// 执行的异步方法
/// </summary>
public Func<Task>? ExecuteActionAsync { get; set; }
/// <summary>
/// 获取能否执行的方法
/// </summary>
public Func<bool>? CanExecuteAction { get; set; }
/// <summary> /// <summary>
/// 能执行的属性 /// 能执行的属性
/// <para>
/// 注意: 仅当 <see cref="CanExecuteAction"/> 为 <see langword="null"/> 时, 此属性才会被使用
/// </para>
/// </summary> /// </summary>
public ObservableValue<bool> CanExecuteProperty { get; } = new(true); public ObservableValue<bool> CanExecuteProperty { get; } = new(true);
@ -64,9 +47,7 @@ public class ObservableCommand : ICommand
{ {
if (r_waiting.Value is true) if (r_waiting.Value is true)
return false; return false;
return CanExecuteAction is null return CanExecuteProperty.Value;
? CanExecuteProperty.Value
: CanExecuteAction?.Invoke() is not false;
} }
/// <summary> /// <summary>
@ -75,7 +56,7 @@ public class ObservableCommand : ICommand
/// <param name="parameter">参数</param> /// <param name="parameter">参数</param>
public async void Execute(object? parameter) public async void Execute(object? parameter)
{ {
ExecuteAction?.Invoke(); ExecuteEvent?.Invoke();
await ExecuteAsync(); await ExecuteAsync();
} }
@ -85,15 +66,39 @@ public class ObservableCommand : ICommand
/// <returns>等待</returns> /// <returns>等待</returns>
private async Task ExecuteAsync() private async Task ExecuteAsync()
{ {
if (ExecuteActionAsync is null) if (AsyncExecuteEvent is null)
return; return;
r_waiting.Value = true; r_waiting.Value = true;
await ExecuteActionAsync.Invoke(); foreach (
var asyncEvent in AsyncExecuteEvent.GetInvocationList().Cast<AsyncExecuteHandler>()
)
await asyncEvent.Invoke();
r_waiting.Value = false; r_waiting.Value = false;
} }
/// <summary> /// <summary>
/// 能否执行属性改变事件 /// 能否执行属性改变事件
/// </summary> /// </summary>
public event EventHandler? CanExecuteChanged; public event EventHandler? CanExecuteChanged;
/// <summary>
/// 执行事件
/// </summary>
public event ExecuteHandler? ExecuteEvent;
/// <summary>
/// 异步执行事件
/// </summary>
public event AsyncExecuteHandler? AsyncExecuteEvent;
/// <summary>
/// 执行
/// </summary>
public delegate void ExecuteHandler();
/// <summary>
/// 异步执行
/// </summary>
/// <returns></returns>
public delegate Task AsyncExecuteHandler();
} }

View File

@ -14,22 +14,13 @@ namespace HKW.HKWViewModels.SimpleObservable;
public class ObservableCommand<T> : ICommand public class ObservableCommand<T> : ICommand
where T : notnull where T : notnull
{ {
/// <inheritdoc cref="ObservableCommand.ExecuteAction"/>
public Action<T?>? ExecuteAction { get; set; }
/// <inheritdoc cref="ObservableCommand.ExecuteActionAsync"/>
public Func<T?, Task>? ExecuteActionAsync { get; set; }
/// <inheritdoc cref="ObservableCommand.CanExecuteAction"/>
public Func<T?, bool>? CanExecuteAction { get; set; }
/// <inheritdoc cref="ObservableCommand.CanExecuteProperty"/> /// <inheritdoc cref="ObservableCommand.CanExecuteProperty"/>
public ObservableValue<bool> CanExecuteProperty { get; } = new(true); public ObservableValue<bool> CanExecuteProperty { get; } = new(true);
/// <inheritdoc cref="ObservableCommand.r_waiting"/> /// <inheritdoc cref="ObservableCommand.r_waiting"/>
private readonly ObservableValue<bool> r_waiting = new(false); private readonly ObservableValue<bool> r_waiting = new(false);
/// <inheritdoc cref="ObservableCommand.ObservableCommand()"/> /// <inheritdoc />
public ObservableCommand() public ObservableCommand()
{ {
CanExecuteProperty.PropertyChanged += InvokeCanExecuteChanged; CanExecuteProperty.PropertyChanged += InvokeCanExecuteChanged;
@ -49,29 +40,44 @@ public class ObservableCommand<T> : ICommand
{ {
if (r_waiting.Value is true) if (r_waiting.Value is true)
return false; return false;
return CanExecuteAction is null return CanExecuteProperty.Value;
? CanExecuteProperty.Value
: CanExecuteAction?.Invoke((T?)parameter) is not false;
} }
/// <inheritdoc cref="ObservableCommand.Execute(object?)"/> /// <inheritdoc cref="ObservableCommand.Execute(object?)"/>
public async void Execute(object? parameter) public async void Execute(object? parameter)
{ {
ExecuteAction?.Invoke((T?)parameter); ExecuteEvent?.Invoke((T?)parameter!);
await ExecuteAsync((T?)parameter); await ExecuteAsync((T?)parameter!);
} }
/// <inheritdoc cref="ObservableCommand.ExecuteActionAsync()"/> /// <inheritdoc cref="ObservableCommand.ExecuteAsync"/>
/// <param name="parameter">参数</param> /// <param name="parameter">参数</param>
private async Task ExecuteAsync(T? parameter) private async Task ExecuteAsync(T parameter)
{ {
if (ExecuteActionAsync is null) if (AsyncExecuteEvent is null)
return; return;
r_waiting.Value = true; r_waiting.Value = true;
await ExecuteActionAsync.Invoke(parameter); foreach (
var asyncEvent in AsyncExecuteEvent.GetInvocationList().Cast<AsyncExecuteHandler>()
)
await asyncEvent.Invoke(parameter);
r_waiting.Value = false; r_waiting.Value = false;
} }
/// <inheritdoc cref="ObservableCommand.CanExecuteChanged"/> /// <inheritdoc cref="ObservableCommand.CanExecuteChanged"/>
public event EventHandler? CanExecuteChanged; public event EventHandler? CanExecuteChanged;
/// <inheritdoc cref="ObservableCommand.ExecuteEvent"/>
public event ExecuteHandler? ExecuteEvent;
/// <inheritdoc cref="ObservableCommand.AsyncExecuteEvent"/>
public event AsyncExecuteHandler? AsyncExecuteEvent;
/// <inheritdoc cref="ObservableCommand.ExecuteHandler"/>
/// <param name="value">值</param>
public delegate void ExecuteHandler(T value);
/// <inheritdoc cref="ObservableCommand.AsyncExecuteHandler"/>
/// <param name="value">值</param>
public delegate Task AsyncExecuteHandler(T value);
} }

View File

@ -102,6 +102,7 @@
<Compile Include="Models\ObservableRange.cs" /> <Compile Include="Models\ObservableRange.cs" />
<Compile Include="Models\PetModel.cs" /> <Compile Include="Models\PetModel.cs" />
<Compile Include="Models\SelectTextModel.cs" /> <Compile Include="Models\SelectTextModel.cs" />
<Compile Include="SimpleObservable\ObservableCommandT.cs" />
<Compile Include="ViewModels\ModEdit\ClickTextEdit\ClickTextEditWindowVM.cs" /> <Compile Include="ViewModels\ModEdit\ClickTextEdit\ClickTextEditWindowVM.cs" />
<Compile Include="ViewModels\ModEdit\ClickTextEdit\ClickTextPageVM.cs" /> <Compile Include="ViewModels\ModEdit\ClickTextEdit\ClickTextPageVM.cs" />
<Compile Include="ViewModels\ModEdit\FoodEdit\FoodPageVM.cs" /> <Compile Include="ViewModels\ModEdit\FoodEdit\FoodPageVM.cs" />
@ -145,7 +146,6 @@
<DesignTimeSharedInput>True</DesignTimeSharedInput> <DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile> </Compile>
<Compile Include="SimpleObservable\ObservableCommand.cs" /> <Compile Include="SimpleObservable\ObservableCommand.cs" />
<Compile Include="SimpleObservable\ObservableCommand{T}.cs" />
<Compile Include="SimpleObservable\ObservableValue.cs" /> <Compile Include="SimpleObservable\ObservableValue.cs" />
<Compile Include="Utils.cs" /> <Compile Include="Utils.cs" />
<Compile Include="Views\ModEdit\FoodEdit\FoodEditWindow.xaml.cs"> <Compile Include="Views\ModEdit\FoodEdit\FoodEditWindow.xaml.cs">

View File

@ -29,9 +29,9 @@ public class ClickTextPageVM
{ {
ShowClickTexts.Value = ClickTexts; ShowClickTexts.Value = ClickTexts;
FilterClickText.ValueChanged += FilterClickText_ValueChanged; FilterClickText.ValueChanged += FilterClickText_ValueChanged;
AddClickTextCommand.ExecuteAction = AddClickText; AddClickTextCommand.ExecuteEvent += AddClickText;
EditClickTextCommand.ExecuteAction = EditClickText; EditClickTextCommand.ExecuteEvent += EditClickText;
RemoveClickTextCommand.ExecuteAction = RemoveClickText; RemoveClickTextCommand.ExecuteEvent += RemoveClickText;
} }
private void FilterClickText_ValueChanged(string value) private void FilterClickText_ValueChanged(string value)

View File

@ -29,8 +29,8 @@ public class FoodEditWindowVM
public FoodEditWindowVM() public FoodEditWindowVM()
{ {
InitializeFoodTypes(); InitializeFoodTypes();
AddImageCommand.ExecuteAction = AddImage; AddImageCommand.ExecuteEvent += AddImage;
ChangeImageCommand.ExecuteAction = ChangeImage; ChangeImageCommand.ExecuteEvent += ChangeImage;
} }
public void Close() { } public void Close() { }

View File

@ -31,9 +31,9 @@ public class FoodPageVM
ShowFoods.Value = Foods; ShowFoods.Value = Foods;
FilterFoodText.ValueChanged += FilterFoodText_ValueChanged; FilterFoodText.ValueChanged += FilterFoodText_ValueChanged;
AddFoodCommand.ExecuteAction = AddFood; AddFoodCommand.ExecuteEvent += AddFood;
EditFoodCommand.ExecuteAction = EditFood; EditFoodCommand.ExecuteEvent += EditFood;
RemoveFoodCommand.ExecuteAction = RemoveFood; RemoveFoodCommand.ExecuteEvent += RemoveFood;
} }
private void FilterFoodText_ValueChanged(string value) private void FilterFoodText_ValueChanged(string value)

View File

@ -32,9 +32,9 @@ public class LowTextPageVM
{ {
ShowLowTexts.Value = LowTexts; ShowLowTexts.Value = LowTexts;
FilterLowText.ValueChanged += FilterLowText_ValueChanged; FilterLowText.ValueChanged += FilterLowText_ValueChanged;
AddLowTextCommand.ExecuteAction = AddLowText; AddLowTextCommand.ExecuteEvent += AddLowText;
EditLowTextCommand.ExecuteAction = EditLowText; EditLowTextCommand.ExecuteEvent += EditLowText;
RemoveLowTextCommand.ExecuteAction = RemoveLowText; RemoveLowTextCommand.ExecuteEvent += RemoveLowText;
} }
private void FilterLowText_ValueChanged(string value) private void FilterLowText_ValueChanged(string value)

View File

@ -79,13 +79,13 @@ public class ModEditWindowVM
ModEditWindow = window; ModEditWindow = window;
CurrentLang.ValueChanged += CurrentLang_ValueChanged; CurrentLang.ValueChanged += CurrentLang_ValueChanged;
AddImageCommand.ExecuteAction += AddImage; AddImageCommand.ExecuteEvent += AddImage;
ChangeImageCommand.ExecuteAction += ChangeImage; ChangeImageCommand.ExecuteEvent += ChangeImage;
AddLangCommand.ExecuteAction += AddLang; AddLangCommand.ExecuteEvent += AddLang;
EditLangCommand.ExecuteAction += EditLang; EditLangCommand.ExecuteEvent += EditLang;
RemoveLangCommand.ExecuteAction += RemoveLang; RemoveLangCommand.ExecuteEvent += RemoveLang;
SaveCommand.ExecuteAction += Save; SaveCommand.ExecuteEvent += Save;
SaveToCommand.ExecuteAction += SaveTo; SaveToCommand.ExecuteEvent += SaveTo;
} }
private void CurrentLang_ValueChanged(string value) private void CurrentLang_ValueChanged(string value)

View File

@ -42,9 +42,9 @@ public class ModMakerWindowVM
LoadHistories(); LoadHistories();
ModMakerWindow = window; ModMakerWindow = window;
ShowHistories.Value = Histories; ShowHistories.Value = Histories;
CreateNewModCommand.ExecuteAction = CreateNewMod; CreateNewModCommand.ExecuteEvent += CreateNewMod;
LoadModFromFileCommand.ExecuteAction = LoadModFromFile; LoadModFromFileCommand.ExecuteEvent += LoadModFromFile;
ClearHistoriesCommand.ExecuteAction = ClearHistories; ClearHistoriesCommand.ExecuteEvent += ClearHistories;
HistoriesFilterText.ValueChanged += ModFilterText_ValueChanged; HistoriesFilterText.ValueChanged += ModFilterText_ValueChanged;
} }