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

WPF ContextMenu,MenuItem command can binding to datacontexts command directly

 <DataGrid.ContextMenu><ContextMenu><MenuItem Header="{Binding FirstMIHeader}"FontSize="50"Width="350"Height="150"Command="{Binding FirstCmd}"CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu},Path=PlacementTarget.SelectedItems}"/></ContextMenu></DataGrid.ContextMenu>private DelCmd firstCmd;
public DelCmd FirstCmd
{get{if (firstCmd == null){firstCmd = new DelCmd(FirstCmdExecuted);}return firstCmd;}
}private void FirstCmdExecuted(object? obj)
{_ = Task.Run(async() =>{var items = ((System.Collections.IList)obj).Cast<Book>()?.ToList();if (items != null && items.Any()){string jsonStr = JsonConvert.SerializeObject(items, Formatting.Indented);string jsonFile = string.Empty;await Application.Current?.Dispatcher?.InvokeAsync(() =>{SaveFileDialog dlg = new SaveFileDialog();dlg.Filter = $"Json Files|*.json";dlg.FileName = $"Json_{DateTime.Now.ToString("yyyyMMddHHmmssffff")}.json";if (dlg.ShowDialog() == true){jsonFile = dlg.FileName;}});using(StreamWriter jsonWriter=new StreamWriter(jsonFile,false,Encoding.UTF8)){jsonWriter.WriteLine(jsonStr);}await Application.Current?.Dispatcher?.InvokeAsync(() =>{MessageBox.Show($"Saved {items.Count} items in {jsonFile}");},System.Windows.Threading.DispatcherPriority.Background);}});            
}private string firstMIHeader="Save In Json";
public string FirstMIHeader
{get{return firstMIHeader;}set{if (value != firstMIHeader){firstMIHeader = value;OnPropertyChanged();}}
}

 

 

Install-Package Newtonsoft.json

 

<Window x:Class="WpfApp10.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:WpfApp10"mc:Ignorable="d"Title="{Binding MainTitle}" WindowState="Maximized"><Window.DataContext><local:MainVM/></Window.DataContext><Grid><DataGrid ItemsSource="{Binding BooksCollection}"VirtualizingPanel.IsVirtualizing="True"VirtualizingPanel.VirtualizationMode="Recycling"VirtualizingPanel.CacheLength="5,5"VirtualizingPanel.CacheLengthUnit="Item"ScrollViewer.IsDeferredScrollingEnabled="True"ScrollViewer.CanContentScroll="True"UseLayoutRounding="True"SnapsToDevicePixels="True"CanUserAddRows="False"AutoGenerateColumns="True"EnableRowVirtualization="True"EnableColumnVirtualization="True"><DataGrid.Resources><Style TargetType="DataGridRow"><Setter Property="FontSize" Value="30"/><Style.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter Property="FontSize" Value="40"/><Setter Property="Foreground" Value="Red"/></Trigger></Style.Triggers></Style></DataGrid.Resources><DataGrid.ContextMenu><ContextMenu><MenuItem Header="{Binding FirstMIHeader}"FontSize="50"Width="350"Height="150"Command="{Binding FirstCmd}"CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu},Path=PlacementTarget.SelectedItems}"/></ContextMenu></DataGrid.ContextMenu></DataGrid></Grid>
</Window>using Microsoft.Win32;
using Newtonsoft.Json;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
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;namespace WpfApp10
{/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}}public class MainVM : INotifyPropertyChanged{string originUrl = "http://localhost:51537/BookService.svc/getbookslist?cnt=";static readonly HttpClient client = new HttpClient();private readonly object isLoadingLock = new object();private readonly SemaphoreSlim semaphoreThrottle = new SemaphoreSlim(10, 10);public MainVM(){if (DesignerProperties.GetIsInDesignMode(new DependencyObject())){return;}_ = Task.Run(async () =>{while (true){await InitBooksCollectionAsync();await Task.Delay(20000);}});}private async Task InitBooksCollectionAsync(int cnt = 1000000){if (!await semaphoreThrottle.WaitAsync(20000)){return;}if (IsLoading){return;}IsLoading = true;try{await Application.Current?.Dispatcher?.InvokeAsync(() =>{MainTitle = $"{DateTime.Now},loading...";}, System.Windows.Threading.DispatcherPriority.Background);string requestUrl = $"{originUrl}{cnt}";await Task.Run(async () =>{string jsonStr = await client.GetStringAsync(requestUrl);if (string.IsNullOrWhiteSpace(jsonStr)){return;}List<Book>? bks = JsonConvert.DeserializeObject<List<Book>>(jsonStr);if (bks != null && bks.Any()){await Application.Current?.Dispatcher?.InvokeAsync(() =>{BooksCollection = new ObservableCollection<Book>(bks);MainTitle = $"{DateTime.Now},FirstID:{BooksCollection.FirstOrDefault()?.Id},LastID:{BooksCollection.LastOrDefault()?.Id}";}, System.Windows.Threading.DispatcherPriority.Background);}});}catch (Exception ex){MessageBox.Show($"{DateTime.Now},exception message {ex?.Message}");}finally{IsLoading = false;semaphoreThrottle.Release();}}private DelCmd firstCmd;public DelCmd FirstCmd{get{if (firstCmd == null){firstCmd = new DelCmd(FirstCmdExecuted);}return firstCmd;}}private void FirstCmdExecuted(object? obj){_ = Task.Run(async() =>{var items = ((System.Collections.IList)obj).Cast<Book>()?.ToList();if (items != null && items.Any()){string jsonStr = JsonConvert.SerializeObject(items, Formatting.Indented);string jsonFile = string.Empty;await Application.Current?.Dispatcher?.InvokeAsync(() =>{SaveFileDialog dlg = new SaveFileDialog();dlg.Filter = $"Json Files|*.json";dlg.FileName = $"Json_{DateTime.Now.ToString("yyyyMMddHHmmssffff")}.json";if (dlg.ShowDialog() == true){jsonFile = dlg.FileName;}});using(StreamWriter jsonWriter=new StreamWriter(jsonFile,false,Encoding.UTF8)){jsonWriter.WriteLine(jsonStr);}await Application.Current?.Dispatcher?.InvokeAsync(() =>{MessageBox.Show($"Saved {items.Count} items in {jsonFile}");},System.Windows.Threading.DispatcherPriority.Background);}});            }private string firstMIHeader="Save In Json";public string FirstMIHeader{get{return firstMIHeader;}set{if (value != firstMIHeader){firstMIHeader = value;OnPropertyChanged();}}}private bool isLoading = false;public bool IsLoading{get{lock (isLoadingLock){return isLoading;}}set{lock (isLoadingLock){if (value != isLoading){isLoading = value;OnPropertyChanged();}}}}private string mainTitle = $"{DateTime.Now}";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 propName = ""){var handler = Volatile.Read(ref PropertyChanged);if (handler == null){return;}handler?.Invoke(this, new PropertyChangedEventArgs(propName));}}public class DelCmd : ICommand{private readonly Action<object?> execute;private readonly Func<object?, bool>? canExecute;public DelCmd(Action<object?> executeValue, Func<object?, bool>? canExecuteValue = null){execute = executeValue;canExecute = canExecuteValue;}public event EventHandler? CanExecuteChanged;public bool CanExecute(object? parameter){return canExecute == null ? true : canExecute(parameter);}public void Execute(object? parameter){if (!CanExecute(parameter)){return;}execute?.Invoke(parameter);}public void RaiseCanExecuteChanged(object? parameter){var handler = Volatile.Read(ref CanExecuteChanged);if (handler == null){return;}if (Application.Current?.Dispatcher?.CheckAccess() == true){handler?.Invoke(parameter, EventArgs.Empty);}else{Application.Current?.Dispatcher?.Invoke(() =>{handler?.Invoke(parameter, EventArgs.Empty);});}}}public class Book{public long Id { get; set; }public string Name { get; set; }public string ISBN { get; set; }public string Abstract { get; set; }public string Author { 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; }}}

 

 

 

 

 

 

 

 

 

 

image

 

 

 

 

 

image

 

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

相关文章:

  • GPT-4o架构解析:低延迟语音与原生多模态统一建模
  • Python+Appium移动自动化实战:从环境搭建到脚本编写完整指南
  • Grok 4.20四Agent模式:提示词工程驱动的显式分片推理
  • Qwen3.5与MiniMax M2.5架构深度对比:GQA、混合注意力与MoE工程落地解析
  • 2026帝王宫海鲜加工饭店口碑排行,业内老饕推荐榜出炉 - 官方资讯
  • xray被动扫描器实战指南:从安装配置到精准漏洞挖掘
  • 2026年6月正规的杏壳活性炭订做厂家推荐,活性炭/椰壳黄金炭/煤质活性炭/食品级活性炭,杏壳活性炭供应商哪家权威 - 品牌推荐师
  • 2026合肥理工学校官方最全招生简章|办学详情、管理模式、升学数据、报名入口全公布 - 教育为先
  • Windows驱动管家:Driver Store Explorer完全使用手册
  • 如何获得赞助:Instagram、活动赞助及其他赞助
  • 鸣潮自动化工具终极指南:基于YOLOv8图像识别的智能辅助解决方案
  • 豆包2.0 Seed 2.0 Code:国产多模态AI编程范式落地实践
  • Web服务器安全加固实战:隐藏版本信息、修复X-Powered-By泄露与点击劫持防护
  • Hermes Agent 本地AI工作台:MiMo V2 Pro白嫖与Telegram网关实战指南
  • 技术突破:如何通过大语言模型重编程实现革命性时间序列预测
  • 2026帝王宫海鲜加工饭店排行榜:内行推荐这5家 - 官方资讯
  • 2026地热井耐高温液位计主流源头厂家排行榜与品牌选型推荐 - 王工聊地下水监测
  • 互联网大厂 Java 求职面试:从 Spring Boot 到微服务架构的深度探讨
  • 合肥高科经济技工学校怎么报名?在哪报名?2026年官网最新发布招生简章|报名流程|招生电话一览 - 教育为先
  • 电瓶车托运不拆电池行吗?2026新规+省钱方案来了 - 快递物流资讯
  • 职教高考和普通高考区别?推荐合肥理工学校! - 教育为先
  • 2026年北京发电机租赁、应急电源车租赁厂家名单及选购参考指南 - 海棠依旧大
  • [Windows]罗技G HUB(Logitech G HUB)旧版本下载地址汇总
  • DeepSeek-V4的减法哲学:如何用架构极简主义突破大模型成本困局
  • 重塑视觉真相:NVIDIA显卡色彩校准工具让广色域显示器回归真实色彩
  • 从零搭建Python+Selenium自动化测试框架:分层架构与核心模块详解
  • Gemini三层次使用路径:从Chrome内置到API开发的完整指南
  • 遵义美食推荐|本地人认证 TOP3!从早到晚吃遍地道黔北风味 - GrowthUME
  • 如何配置远程的ubuntu服务器以使在本地windows电脑上可以进行X11图形转发——ssh远程X11转发的配置
  • GLM-5全栈工程解析:MoE架构、IcePop训推一致与DSA稀疏注意力