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

WPF implement DelCommand inherited from ICommand from scratch

public class DelCommand : ICommand
{private Action<object?> execute;private Predicate<object?> canExecute;public DelCommand(Action<object?> executeValue, Predicate<object?> canExecuteValue =null){execute = executeValue;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 void Execute(object? parameter){execute(parameter);}
}

 

 

 

<Window x:Class="WpfApp1.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:WpfApp1"mc:Ignorable="d"WindowState="Maximized"Title="{Binding MainTitle}"><Window.DataContext><local:MainVM/></Window.DataContext><Window.Resources><local:ImgUrlToImageSourceConverter x:Key="ImgUrlToImageSourceConverter"/>        </Window.Resources><Grid><DataGrid ItemsSource="{Binding BooksCollection}"VirtualizingPanel.IsVirtualizing="True"VirtualizingPanel.VirtualizationMode="Recycling"VirtualizingPanel.CacheLength="2,2"VirtualizingPanel.CacheLengthUnit="Item"ScrollViewer.CanContentScroll="True"ScrollViewer.IsDeferredScrollingEnabled="True"AutoGenerateColumns="False"CanUserAddRows="False"><DataGrid.Columns><DataGridTemplateColumn><DataGridTemplateColumn.CellTemplate><DataTemplate><Grid Width="{Binding DataContext.GridWidth,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"Height="{Binding DataContext.GridHeight,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"><Grid.Resources><Style TargetType="TextBlock"><Setter Property="FontSize" Value="30"/><Style.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter Property="Foreground" Value="Red"/><Setter Property="FontSize" Value="100"/></Trigger></Style.Triggers></Style></Grid.Resources><Grid.Background><ImageBrush ImageSource="{Binding ImgUrl,Converter={StaticResource ImgUrlToImageSourceConverter}}"Stretch="Uniform"/></Grid.Background><Grid.RowDefinitions><RowDefinition/><RowDefinition/></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/><ColumnDefinition/></Grid.ColumnDefinitions><TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Id}"/><TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Name}"/><TextBlock Grid.Row="0" Grid.Column="2" Text="{Binding Topic}"/><TextBlock Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" Text="{Binding ISBN}"/></Grid></DataTemplate></DataGridTemplateColumn.CellTemplate></DataGridTemplateColumn></DataGrid.Columns></DataGrid></Grid>
</Window>using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
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;namespace WpfApp1
{/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();RenderOptions.ProcessRenderMode=System.Windows.Interop.RenderMode.Default;this.Loaded += async (s, e) =>{var vm = this.DataContext as MainVM;if(vm!=null){var fe = this.Content as FrameworkElement;if(fe!=null){vm.GridWidth= fe.ActualWidth;vm.GridHeight= fe.ActualHeight;}await vm.InitBooksCollection(30500100);}};}}public class MainVM : INotifyPropertyChanged{public MainVM(){}public async Task InitBooksCollection(int cnt=10000000){var img_dir = @"../../../Images";if (!Directory.Exists(img_dir)){return;}var imgs=Directory.GetFiles(img_dir);if(imgs==null ||!imgs.Any()){return;}int imgsCnt = imgs.Count();List<Book> booksList=new List<Book>();BooksCollection = new ObservableCollection<Book>();for (int i=0;i<cnt+1;i++){booksList.Add(new Book(){Id=i,Name=$"Name_{i}",ISBN=$"ISBN_{i}_{Guid.NewGuid():N}",Topic=$"Topic_{i}",ImgUrl = imgs[i%imgsCnt]});if (i%100000==0){await PopulateBooksCollectionAsync(booksList, i);}}if(booksList.Any()){await PopulateBooksCollectionAsync(booksList, cnt);}}private async Task PopulateBooksCollectionAsync(List<Book> booksList, int i){var tempList = booksList.ToList();booksList.Clear();            await Application.Current.Dispatcher.InvokeAsync(() =>{foreach (var item in tempList){BooksCollection.Add(item);}MainTitle = $"{DateTime.Now},i:{i},{GetMem()}";},System.Windows.Threading.DispatcherPriority.Background);}private ObservableCollection<Book> booksCollection;public ObservableCollection<Book> BooksCollection{get{return booksCollection; }set{if (booksCollection != value){booksCollection = value;OnPropertyChanged();}}}private double gridWidth;public double GridWidth{get{return gridWidth; }set{if (gridWidth != value){gridWidth = value;OnPropertyChanged();}}}private double gridHeight;public double GridHeight{get{return gridHeight; }set{if(gridHeight!=value){gridHeight = value;OnPropertyChanged();}}}private string mainTitle="";public string MainTitle{get{return mainTitle; }set{if(mainTitle!=value){mainTitle = value;OnPropertyChanged();}}}public string GetMem(){var proc=Process.GetCurrentProcess();return $"Memory {proc.PrivateMemorySize64 / 1024 / 1024:.2f}M";}public event PropertyChangedEventHandler? PropertyChanged;private void OnPropertyChanged([CallerMemberName]string propertyName=""){var handler = PropertyChanged;if(handler!=null){handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));}}}public class ImgUrlToImageSourceConverter : IValueConverter{Dictionary<string,ImageSource> imgDic=new Dictionary<string,ImageSource>();public object Convert(object value, Type targetType, object parameter, CultureInfo culture){var imgUrl=value as string;if(!string.IsNullOrWhiteSpace(imgUrl) && File.Exists(imgUrl)){if(imgDic.ContainsKey(imgUrl)){return imgDic[imgUrl];}BitmapImage bmi=new BitmapImage();bmi.BeginInit();bmi.UriSource = new Uri(imgUrl, UriKind.RelativeOrAbsolute);bmi.CacheOption = BitmapCacheOption.OnDemand;bmi.EndInit();if(bmi.CanFreeze){bmi.Freeze();}imgDic[imgUrl] = bmi;return bmi;}return null;}public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){throw new NotImplementedException();}}public class Book{public int Id { get; set; }public string Name { get; set; }public string Topic { get; set;  }public string ISBN { get; set; }public string ImgUrl { get; set;  }}public class DelCommand : ICommand{private Action<object?> execute;private Predicate<object?> canExecute;public DelCommand(Action<object?> executeValue, Predicate<object?> canExecuteValue =null){execute = executeValue;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 void Execute(object? parameter){execute(parameter);}}
}

 

image

 

 

 

 

image

 

 

 

image

 

 

 

image

 

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

相关文章:

  • **0-1 背包问题的分支限界法(Branch and Bound)求解框架**,核心融合了**贪心松弛上界估计**与**精确剪枝策略**
  • N9e配置电话告警,实现故障的电话(语音)通知
  • Grafana + Loki 使用说明
  • windows上子系统WSL下载和使用
  • linux系统 Qt 通常的目录结构
  • 算法备案分类详细及合规要点整理(2026年更新版)
  • MySQL数据库从win导出成_db.sql复制到linux
  • EC2 使用 dnsmasq 本地缓存 + EKS 使用 NodeLocalDNS
  • 基于 Kubernetes + Helm 部署高可用 ETCD 集群
  • OS 核心知识点全解析(一)
  • Redis 迁移方案-RedisShake
  • qml可拖动折线图
  • 【linuxqt】qsql_mysql.cpp:57:10: fatal error: QtSql/private/qsqldriver_p.h: No such file or directory
  • 我草我怎么这么牛
  • 基于 AWS Global Accelerator 实现全球低延迟访问-RapidX 全球加速方案
  • day96(2.25)——leetcode面试经典150
  • 【Linux】进程的页表详解
  • YOLO26最新创新改进系列:主干网络全新设计——EfficientNetV2-BackBone ,引入渐进式学习策略、自适应正则强度调整机制,共同优化训练速度和参数效率,全方位提升模型检测性能!!
  • YOLO26最新创新改进系列:融入AKConv(可改变核卷积),加强特征提取,任意数量的参数和任意采样形状,为网络开销和性能之间的权衡提供了更丰富的选择。 拉升检测性能!
  • 瑞芯微开发板开机自启动设置
  • FastAsyncWorldEdit zh-cn strings.json 中文汉化
  • **0-1 背包问题中回溯法的搜索过程、通用解题步骤及两种算法实现框架(递归与非递归)**,是算法设计与分析中的经典范例
  • SRE 团队体系建设之路
  • 惊叹!大数据数据增强如何颠覆传统模式
  • int[] 与 integer[] 相互转换
  • Amazon EMR 高可用 EMR 部署注意事项及关键配置
  • SolidPlant 2020管道设计软件安装包(含详细图文教程)|兼容SolidWorks 2017及以上版本
  • 【踩坑】MacOS26上的浏览器无法显示麦克风/摄像头列表
  • 【DFS】BISHI77数水坑
  • SimpleDateFormat(YYYY-MM-dd)格式化时间出现了bug?