当前位置: 首页 > news >正文

WPF implement ICommand with async execute

public class DelCommand : ICommand
{private Action<object?>? syncExecute;private readonly Func<object?, Task> asyncExecute;private Predicate<object?>? canExecute;public DelCommand(Action<object?>? executeValue, Predicate<object?>? canExecuteValue = null){syncExecute = executeValue ?? throw new ArgumentNullException(nameof(executeValue));canExecute = canExecuteValue;}public DelCommand(Func<object?, Task> asyncExecuteValue, Predicate<object?>? canExecuteValue = null){asyncExecute = asyncExecuteValue ?? throw new ArgumentNullException(nameof(asyncExecuteValue));canExecute = canExecuteValue;}public event EventHandler? CanExecuteChanged{add{CommandManager.RequerySuggested += value;}remove{CommandManager.RequerySuggested -= value;}}public bool CanExecute(object? parameter){return canExecute == null ? true : canExecute(parameter);}public async void Execute(object? parameter){if (!CanExecute(parameter)){return;}if (asyncExecute != null){await asyncExecute(parameter);}else if (syncExecute != null){syncExecute(parameter);}}
}private ICommand mouseDownCommand;
public ICommand MouseDownCommand
{get{if (mouseDownCommand == null){mouseDownCommand = new DelCommand(MouseDownCommandExecuted);}return mouseDownCommand;}
}private async Task MouseDownCommandExecuted(object? obj)
{var btnEventArgs = obj as MouseButtonEventArgs;if (btnEventArgs != null){await InitBooksCollectionAsync();string msg = $"MinId:{BooksCollection.OrderBy(x => x.Id).FirstOrDefault()?.Id}\n" +$"MaxId:{BooksCollection.OrderByDescending(x => x.Id).FirstOrDefault()?.Id}";MessageBox.Show($"{msg}", $"{DateTime.Now}");}
}private async Task InitBooksCollectionAsync()
{string dataUrl = "https://localhost:7146/api/book";using (HttpClient client = new HttpClient()){string jsonStr = await client.GetStringAsync(dataUrl);if (!string.IsNullOrWhiteSpace(jsonStr)){List<Book>? bksList = JsonConvert.DeserializeObject<List<Book>>(jsonStr);if (bksList != null && bksList.Any()){BooksCollection = new ObservableCollection<Book>(bksList);MainTitle = $"{DateTime.Now},loaded last idx:{bksList.OrderByDescending(x => x.Id).FirstOrDefault()?.Id}";}}}
}

 

 

 

image

 

 

 

 

image

 

 

image

 

 

 

//WebAPI
namespace WebApplication2.Models
{public class Book{public int Id {  get; set; }public string Name {  get; set; }public string ISBN {  get; set; }public string Comment { get; set; }public string Content { get;set;  }        public string Summary { get; set;  }public string Title { get; set;  }public string Topic {  get; set; }}
}
using WebApplication2.Models;namespace WebApplication2.Services
{public class BookService:IDisposable{int idx = 0;private int GetIdx(){return Interlocked.Increment(ref idx);}public List<Book> GetBooksList(int cnt=10000){List<Book> booksList=new List<Book>();for(int i=0;i<cnt;i++){int a=GetIdx();booksList.Add(new Book(){Id = a,Name = $"Name_{a}",ISBN = $"ISBN_{a}_{Guid.NewGuid():N}",Comment =$"Comment_{a}",Content=$"Content_{a}",Title=$"Title_{a}",Topic=$"Topic_{a}"});}return booksList;}public void Dispose(){idx = 0;}}
}
using Microsoft.AspNetCore.Mvc;
using WebApplication2.Models;
using WebApplication2.Services;namespace WebApplication2.Controllers
{[ApiController][Route("api/[controller]")]public class BookController : Controller{private BookService bkService;public BookController(BookService bkServiceValue){bkService= bkServiceValue;}[HttpGet][ProducesResponseType(StatusCodes.Status200OK)]public ActionResult<List<Book>> GetBooksList(){var bksList = bkService.GetBooksList();return Ok(bksList);}}
}using WebApplication2.Services;namespace WebApplication2
{public class Program{public static void Main(string[] args){var builder = WebApplication.CreateBuilder(args);// Add services to the container.
builder.Services.AddControllers();// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
            builder.Services.AddOpenApi();builder.Services.AddSingleton<BookService>();var app = builder.Build();// Configure the HTTP request pipeline.if (app.Environment.IsDevelopment()){app.MapOpenApi();}app.UseHttpsRedirection();app.UseAuthorization();app.MapControllers();app.Run();}}
}//WPF
<Window x:Class="WpfApp7.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfApp7"xmlns:behavior="http://schemas.microsoft.com/xaml/behaviors"mc:Ignorable="d"WindowState="Maximized"Title="{Binding MainTitle}" Height="450" Width="800"><behavior:Interaction.Triggers><behavior:EventTrigger EventName="MouseDown"><behavior:InvokeCommandActionCommand="{Binding MouseDownCommand}"PassEventArgsToCommand="True"/></behavior:EventTrigger></behavior:Interaction.Triggers><Window.DataContext><local:MainVM/></Window.DataContext><Grid><DataGrid ItemsSource="{Binding BooksCollection}"IsReadOnly="True"VirtualizingPanel.IsVirtualizing="True"VirtualizingPanel.VirtualizationMode="Recycling"EnableRowVirtualization="True"EnableColumnVirtualization="True"ScrollViewer.CanContentScroll="True"ScrollViewer.IsDeferredScrollingEnabled="True"VirtualizingPanel.CacheLength="2,2"VirtualizingPanel.CacheLengthUnit="Item"AutoGenerateColumns="True"CanUserAddRows="False"><DataGrid.Resources><Style TargetType="DataGridRow"><Setter Property="FontSize" Value="30"/><Style.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter Property="FontSize" Value="50"/><Setter Property="Foreground" Value="Red"/></Trigger></Style.Triggers></Style></DataGrid.Resources><behavior:Interaction.Triggers><behavior:EventTrigger EventName="PreviewMouseDown"><behavior:InvokeCommandActionCommand="{Binding MouseDownCommand}"PassEventArgsToCommand="True"/></behavior:EventTrigger></behavior:Interaction.Triggers></DataGrid></Grid>
</Window>using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Newtonsoft.Json;namespace WpfApp7
{/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}}public class MainVM : INotifyPropertyChanged{public MainVM(){_=InitBooksCollectionAsync();}private ICommand mouseDownCommand;public ICommand MouseDownCommand{get{if (mouseDownCommand == null){mouseDownCommand = new DelCommand(MouseDownCommandExecuted);}return mouseDownCommand;}}private async Task MouseDownCommandExecuted(object? obj){var btnEventArgs = obj as MouseButtonEventArgs;if (btnEventArgs != null){await InitBooksCollectionAsync();string msg = $"MinId:{BooksCollection.OrderBy(x => x.Id).FirstOrDefault()?.Id}\n" +$"MaxId:{BooksCollection.OrderByDescending(x => x.Id).FirstOrDefault()?.Id}";MessageBox.Show($"{msg}", $"{DateTime.Now}");}}private async Task InitBooksCollectionAsync(){string dataUrl = "https://localhost:7146/api/book";using (HttpClient client = new HttpClient()){string jsonStr = await client.GetStringAsync(dataUrl);if (!string.IsNullOrWhiteSpace(jsonStr)){List<Book>? bksList = JsonConvert.DeserializeObject<List<Book>>(jsonStr);if (bksList != null && bksList.Any()){BooksCollection = new ObservableCollection<Book>(bksList);MainTitle = $"{DateTime.Now},loaded last idx:{bksList.OrderByDescending(x => x.Id).FirstOrDefault()?.Id}";}}}}private string mainTitle="";public string MainTitle{get{return mainTitle;}set{if (value != mainTitle){mainTitle = value;OnPropertyChanged();}}}private ObservableCollection<Book> booksCollection;public ObservableCollection<Book> BooksCollection{get{return booksCollection;}set{if (value != booksCollection){booksCollection = value;OnPropertyChanged();}}}public event PropertyChangedEventHandler? PropertyChanged;private void OnPropertyChanged([CallerMemberName] string propertyName = ""){var handler = PropertyChanged;if (handler != null){handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));}}}public class DelCommand : ICommand{private Action<object?>? syncExecute;private readonly Func<object?, Task> asyncExecute;private Predicate<object?>? canExecute;public DelCommand(Action<object?>? executeValue, Predicate<object?>? canExecuteValue = null){syncExecute = executeValue ?? throw new ArgumentNullException(nameof(executeValue));canExecute = canExecuteValue;}public DelCommand(Func<object?, Task> asyncExecuteValue, Predicate<object?>? canExecuteValue = null){asyncExecute = asyncExecuteValue ?? throw new ArgumentNullException(nameof(asyncExecuteValue));canExecute = canExecuteValue;}public event EventHandler? CanExecuteChanged{add{CommandManager.RequerySuggested += value;}remove{CommandManager.RequerySuggested -= value;}}public bool CanExecute(object? parameter){return canExecute == null ? true : canExecute(parameter);}public async void Execute(object? parameter){if (!CanExecute(parameter)){return;}if (asyncExecute != null){await asyncExecute(parameter);}else if (syncExecute != null){syncExecute(parameter);}}}public class Book{public int Id { get; set; }public string Name { get; set; }public string ISBN { get; set; }public string Comment { get; set; }public string Content { get; set; }public string Summary { get; set; }public string Title { get; set; }public string Topic { get; set; }}
}

 

http://www.jsqmd.com/news/492819/

相关文章:

  • 基于Qwen3-ForcedAligner-0.6B的智能字幕生成系统:SpringBoot整合实战
  • 【2026年拼多多春招- 3月15日 -第三题- 多多的配送轨迹】(题目+思路+JavaC++Python解析+在线测试)
  • Gateway 服务器 WebSocket 创建与处理流程分析
  • STM入门(12)
  • Qwen3-14B保姆级部署教程:3步搞定企业级AI客服,小白也能快速上手
  • YOLO26实战全流程:从数据集标注到端到端无NMS推理(附ProgLoss调参技巧)
  • BV电视版 0.3.14.r877 | 纯净好用的第三方B站TV,支持8K视频
  • 如何用Python+OpenCV快速搭建草莓病虫害检测系统(附数据集下载)
  • 运维3年裸辞转行:告别7×24小时背锅,我用4个月逆袭上岸(附全流程实操指南)
  • 亚洲美女-造相Z-Turbo效果对比:Z-Image-Turbo基模 vs LoRA微调版亚洲特征强化分析
  • Phi-3-vision-128k-instruct惊艳效果展示:高精度图文理解生成作品集
  • 从实验室到生产线:YOLOv11多任务统一框架(检测+分割+姿态估计)行业应用
  • Docker 27正式版工业部署实战指南:从CI/CD流水线到OT网络隔离的7大关键配置
  • 比迪丽AI绘画Anaconda环境配置:科学计算与艺术创作完美结合
  • 让照片活起来:Image-to-Video图像转视频生成器实战体验
  • Phi-3-vision-128k-instruct镜像免配置:Docker一键拉起+Chainlit前端自动对接
  • 内网安全部署方案:Qwen3-VL:30B在内网穿透环境下的加密通信实现
  • 酷9多线 1.7.7.8(内置35源) | 魔改版,内置35条直播源,频道非常丰富
  • 弦音墨影参数详解:视觉定位模块阈值、帧采样率与响应延迟调优
  • 在线式UPS设计:双输入无感切换与数字模拟混合控制
  • Dify Rerank插件一键部署教程:从零下载、5步安装、实测QPS提升2.3倍的完整链路
  • Spring_couplet_generation 错误排查指南:解决403 Forbidden等常见网络错误
  • 高级 RAG 技术:查询转换与查询分解
  • Face Analysis WebUI模型微调指南:定制化人脸识别系统开发
  • STC32G12K128核心板:高可靠性工业级8051开发平台
  • 法环
  • 通义千问3-Reranker-0.6B优化电商产品评论分析
  • Phi-3-vision-128k-instruct实战落地:跨境电商多语言商品图理解与翻译辅助
  • Visual Studio Code初次使用注意事项
  • OWL ADVENTURE 小说解析器增强:基于封面与插图的智能分类与推荐