From 4f1c92c82b7a2d71d1ff881e4cd2f6f94ebc7d94 Mon Sep 17 00:00:00 2001 From: Hakoyu <Hakoyu@outlook.com> Date: Wed, 6 Sep 2023 17:22:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20SimpleObservable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SimpleObservable/ObservableCommand.cs | 55 ++++++++++--------- ...bleCommand{T}.cs => ObservableCommandT.cs} | 44 ++++++++------- VPet.ModMaker/VPet.ModMaker.csproj | 2 +- .../ModEdit/ClickTextEdit/ClickTextPageVM.cs | 6 +- .../ModEdit/FoodEdit/FoodEditWindowVM.cs | 4 +- .../ViewModels/ModEdit/FoodEdit/FoodPageVM.cs | 6 +- .../ModEdit/LowTextEdit/LowTextPageVM.cs | 6 +- .../ViewModels/ModEdit/ModEditWindowVM.cs | 14 ++--- VPet.ModMaker/ViewModels/ModMakerWindowVM.cs | 6 +- 9 files changed, 77 insertions(+), 66 deletions(-) rename VPet.ModMaker/SimpleObservable/{ObservableCommand{T}.cs => ObservableCommandT.cs} (61%) diff --git a/VPet.ModMaker/SimpleObservable/ObservableCommand.cs b/VPet.ModMaker/SimpleObservable/ObservableCommand.cs index 5c10db1..3a4a9e3 100644 --- a/VPet.ModMaker/SimpleObservable/ObservableCommand.cs +++ b/VPet.ModMaker/SimpleObservable/ObservableCommand.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -12,26 +13,8 @@ namespace HKW.HKWViewModels.SimpleObservable; /// </summary> 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> /// 能执行的属性 - /// <para> - /// 注意: 仅当 <see cref="CanExecuteAction"/> 为 <see langword="null"/> 时, 此属性才会被使用 - /// </para> /// </summary> public ObservableValue<bool> CanExecuteProperty { get; } = new(true); @@ -64,9 +47,7 @@ public class ObservableCommand : ICommand { if (r_waiting.Value is true) return false; - return CanExecuteAction is null - ? CanExecuteProperty.Value - : CanExecuteAction?.Invoke() is not false; + return CanExecuteProperty.Value; } /// <summary> @@ -75,7 +56,7 @@ public class ObservableCommand : ICommand /// <param name="parameter">参数</param> public async void Execute(object? parameter) { - ExecuteAction?.Invoke(); + ExecuteEvent?.Invoke(); await ExecuteAsync(); } @@ -85,15 +66,39 @@ public class ObservableCommand : ICommand /// <returns>等待</returns> private async Task ExecuteAsync() { - if (ExecuteActionAsync is null) + if (AsyncExecuteEvent is null) return; r_waiting.Value = true; - await ExecuteActionAsync.Invoke(); + foreach ( + var asyncEvent in AsyncExecuteEvent.GetInvocationList().Cast<AsyncExecuteHandler>() + ) + await asyncEvent.Invoke(); r_waiting.Value = false; } /// <summary> - /// 能否执行属性被改变事件 + /// 能否执行属性改变后事件 /// </summary> 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(); } diff --git a/VPet.ModMaker/SimpleObservable/ObservableCommand{T}.cs b/VPet.ModMaker/SimpleObservable/ObservableCommandT.cs similarity index 61% rename from VPet.ModMaker/SimpleObservable/ObservableCommand{T}.cs rename to VPet.ModMaker/SimpleObservable/ObservableCommandT.cs index 5bdee45..db83d80 100644 --- a/VPet.ModMaker/SimpleObservable/ObservableCommand{T}.cs +++ b/VPet.ModMaker/SimpleObservable/ObservableCommandT.cs @@ -14,22 +14,13 @@ namespace HKW.HKWViewModels.SimpleObservable; public class ObservableCommand<T> : ICommand 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"/> public ObservableValue<bool> CanExecuteProperty { get; } = new(true); /// <inheritdoc cref="ObservableCommand.r_waiting"/> private readonly ObservableValue<bool> r_waiting = new(false); - /// <inheritdoc cref="ObservableCommand.ObservableCommand()"/> + /// <inheritdoc /> public ObservableCommand() { CanExecuteProperty.PropertyChanged += InvokeCanExecuteChanged; @@ -49,29 +40,44 @@ public class ObservableCommand<T> : ICommand { if (r_waiting.Value is true) return false; - return CanExecuteAction is null - ? CanExecuteProperty.Value - : CanExecuteAction?.Invoke((T?)parameter) is not false; + return CanExecuteProperty.Value; } /// <inheritdoc cref="ObservableCommand.Execute(object?)"/> public async void Execute(object? parameter) { - ExecuteAction?.Invoke((T?)parameter); - await ExecuteAsync((T?)parameter); + ExecuteEvent?.Invoke((T?)parameter!); + await ExecuteAsync((T?)parameter!); } - /// <inheritdoc cref="ObservableCommand.ExecuteActionAsync()"/> + /// <inheritdoc cref="ObservableCommand.ExecuteAsync"/> /// <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; r_waiting.Value = true; - await ExecuteActionAsync.Invoke(parameter); + foreach ( + var asyncEvent in AsyncExecuteEvent.GetInvocationList().Cast<AsyncExecuteHandler>() + ) + await asyncEvent.Invoke(parameter); r_waiting.Value = false; } /// <inheritdoc cref="ObservableCommand.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); } diff --git a/VPet.ModMaker/VPet.ModMaker.csproj b/VPet.ModMaker/VPet.ModMaker.csproj index 955df78..7d2a622 100644 --- a/VPet.ModMaker/VPet.ModMaker.csproj +++ b/VPet.ModMaker/VPet.ModMaker.csproj @@ -102,6 +102,7 @@ <Compile Include="Models\ObservableRange.cs" /> <Compile Include="Models\PetModel.cs" /> <Compile Include="Models\SelectTextModel.cs" /> + <Compile Include="SimpleObservable\ObservableCommandT.cs" /> <Compile Include="ViewModels\ModEdit\ClickTextEdit\ClickTextEditWindowVM.cs" /> <Compile Include="ViewModels\ModEdit\ClickTextEdit\ClickTextPageVM.cs" /> <Compile Include="ViewModels\ModEdit\FoodEdit\FoodPageVM.cs" /> @@ -145,7 +146,6 @@ <DesignTimeSharedInput>True</DesignTimeSharedInput> </Compile> <Compile Include="SimpleObservable\ObservableCommand.cs" /> - <Compile Include="SimpleObservable\ObservableCommand{T}.cs" /> <Compile Include="SimpleObservable\ObservableValue.cs" /> <Compile Include="Utils.cs" /> <Compile Include="Views\ModEdit\FoodEdit\FoodEditWindow.xaml.cs"> diff --git a/VPet.ModMaker/ViewModels/ModEdit/ClickTextEdit/ClickTextPageVM.cs b/VPet.ModMaker/ViewModels/ModEdit/ClickTextEdit/ClickTextPageVM.cs index 7aa697e..a2f1eb9 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/ClickTextEdit/ClickTextPageVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/ClickTextEdit/ClickTextPageVM.cs @@ -29,9 +29,9 @@ public class ClickTextPageVM { ShowClickTexts.Value = ClickTexts; FilterClickText.ValueChanged += FilterClickText_ValueChanged; - AddClickTextCommand.ExecuteAction = AddClickText; - EditClickTextCommand.ExecuteAction = EditClickText; - RemoveClickTextCommand.ExecuteAction = RemoveClickText; + AddClickTextCommand.ExecuteEvent += AddClickText; + EditClickTextCommand.ExecuteEvent += EditClickText; + RemoveClickTextCommand.ExecuteEvent += RemoveClickText; } private void FilterClickText_ValueChanged(string value) diff --git a/VPet.ModMaker/ViewModels/ModEdit/FoodEdit/FoodEditWindowVM.cs b/VPet.ModMaker/ViewModels/ModEdit/FoodEdit/FoodEditWindowVM.cs index ab21b8a..3aec3ca 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/FoodEdit/FoodEditWindowVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/FoodEdit/FoodEditWindowVM.cs @@ -29,8 +29,8 @@ public class FoodEditWindowVM public FoodEditWindowVM() { InitializeFoodTypes(); - AddImageCommand.ExecuteAction = AddImage; - ChangeImageCommand.ExecuteAction = ChangeImage; + AddImageCommand.ExecuteEvent += AddImage; + ChangeImageCommand.ExecuteEvent += ChangeImage; } public void Close() { } diff --git a/VPet.ModMaker/ViewModels/ModEdit/FoodEdit/FoodPageVM.cs b/VPet.ModMaker/ViewModels/ModEdit/FoodEdit/FoodPageVM.cs index 124486e..4d6fb92 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/FoodEdit/FoodPageVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/FoodEdit/FoodPageVM.cs @@ -31,9 +31,9 @@ public class FoodPageVM ShowFoods.Value = Foods; FilterFoodText.ValueChanged += FilterFoodText_ValueChanged; - AddFoodCommand.ExecuteAction = AddFood; - EditFoodCommand.ExecuteAction = EditFood; - RemoveFoodCommand.ExecuteAction = RemoveFood; + AddFoodCommand.ExecuteEvent += AddFood; + EditFoodCommand.ExecuteEvent += EditFood; + RemoveFoodCommand.ExecuteEvent += RemoveFood; } private void FilterFoodText_ValueChanged(string value) diff --git a/VPet.ModMaker/ViewModels/ModEdit/LowTextEdit/LowTextPageVM.cs b/VPet.ModMaker/ViewModels/ModEdit/LowTextEdit/LowTextPageVM.cs index 2474c77..12f072a 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/LowTextEdit/LowTextPageVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/LowTextEdit/LowTextPageVM.cs @@ -32,9 +32,9 @@ public class LowTextPageVM { ShowLowTexts.Value = LowTexts; FilterLowText.ValueChanged += FilterLowText_ValueChanged; - AddLowTextCommand.ExecuteAction = AddLowText; - EditLowTextCommand.ExecuteAction = EditLowText; - RemoveLowTextCommand.ExecuteAction = RemoveLowText; + AddLowTextCommand.ExecuteEvent += AddLowText; + EditLowTextCommand.ExecuteEvent += EditLowText; + RemoveLowTextCommand.ExecuteEvent += RemoveLowText; } private void FilterLowText_ValueChanged(string value) diff --git a/VPet.ModMaker/ViewModels/ModEdit/ModEditWindowVM.cs b/VPet.ModMaker/ViewModels/ModEdit/ModEditWindowVM.cs index 44a5436..92913b1 100644 --- a/VPet.ModMaker/ViewModels/ModEdit/ModEditWindowVM.cs +++ b/VPet.ModMaker/ViewModels/ModEdit/ModEditWindowVM.cs @@ -79,13 +79,13 @@ public class ModEditWindowVM ModEditWindow = window; CurrentLang.ValueChanged += CurrentLang_ValueChanged; - AddImageCommand.ExecuteAction += AddImage; - ChangeImageCommand.ExecuteAction += ChangeImage; - AddLangCommand.ExecuteAction += AddLang; - EditLangCommand.ExecuteAction += EditLang; - RemoveLangCommand.ExecuteAction += RemoveLang; - SaveCommand.ExecuteAction += Save; - SaveToCommand.ExecuteAction += SaveTo; + AddImageCommand.ExecuteEvent += AddImage; + ChangeImageCommand.ExecuteEvent += ChangeImage; + AddLangCommand.ExecuteEvent += AddLang; + EditLangCommand.ExecuteEvent += EditLang; + RemoveLangCommand.ExecuteEvent += RemoveLang; + SaveCommand.ExecuteEvent += Save; + SaveToCommand.ExecuteEvent += SaveTo; } private void CurrentLang_ValueChanged(string value) diff --git a/VPet.ModMaker/ViewModels/ModMakerWindowVM.cs b/VPet.ModMaker/ViewModels/ModMakerWindowVM.cs index 4adc76f..cd73fb8 100644 --- a/VPet.ModMaker/ViewModels/ModMakerWindowVM.cs +++ b/VPet.ModMaker/ViewModels/ModMakerWindowVM.cs @@ -42,9 +42,9 @@ public class ModMakerWindowVM LoadHistories(); ModMakerWindow = window; ShowHistories.Value = Histories; - CreateNewModCommand.ExecuteAction = CreateNewMod; - LoadModFromFileCommand.ExecuteAction = LoadModFromFile; - ClearHistoriesCommand.ExecuteAction = ClearHistories; + CreateNewModCommand.ExecuteEvent += CreateNewMod; + LoadModFromFileCommand.ExecuteEvent += LoadModFromFile; + ClearHistoriesCommand.ExecuteEvent += ClearHistories; HistoriesFilterText.ValueChanged += ModFilterText_ValueChanged; }