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

WPF loading data asynchronously and contextmenu save as json in mvvm

Install-Package Prism.Wpf;
Install-Package Prism.DryIOC;
Install-Package System.Text.Json;
<prism:PrismApplication x:Class="WpfApp36.App"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:WpfApp36"xmlns:prism="http://prismlibrary.com/"><prism:PrismApplication.Resources></prism:PrismApplication.Resources>
</prism:PrismApplication>
using System.Configuration;
using System.Data;
using System.Windows;namespace WpfApp36
{/// <summary>/// Interaction logic for App.xaml/// </summary>public partial class App : PrismApplication{protected override Window CreateShell(){return Container.Resolve<MainWindow>();}protected override void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.RegisterSingleton<IIDService, IDService>();containerRegistry.RegisterSingleton<IISBNService,ISBNService>();containerRegistry.RegisterSingleton<INameService, NameService>();containerRegistry.Register<MainWindow>();containerRegistry.Register<MainVM>();}}}
<Window x:Class="WpfApp36.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:WpfApp36"mc:Ignorable="d"WindowState="Maximized"Title="{Binding MainTitle}" Height="450" Width="800"><Grid><DataGrid ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"VirtualizingPanel.IsVirtualizing="True"VirtualizingPanel.CacheLengthUnit="Item"VirtualizingPanel.CacheLength="2,2"VirtualizingPanel.VirtualizationMode="Recycling"ScrollViewer.IsDeferredScrollingEnabled="True"ScrollViewer.CanContentScroll="True"FontSize="30"AutoGenerateColumns="True"CanUserAddRows="False"IsReadOnly="True"><DataGrid.ContextMenu><ContextMenu><MenuItem Header="Save As Json File"Command="{Binding SaveAsJsonFileCommand}"CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu},Path=PlacementTarget}"/></ContextMenu></DataGrid.ContextMenu></DataGrid></Grid>
</Window>
using Microsoft.Win32;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;namespace WpfApp36
{/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainWindow : Window{public MainWindow(MainVM vm){InitializeComponent();this.DataContext = vm;this.Loaded += async (s, e) =>{await vm.InitBooksCollection();};}}public class MainVM : INotifyPropertyChanged{private IIDService idService;private INameService nameService;private IISBNService isbnService;public MainVM(IIDService idServiceValue, INameService nameServiceValue, IISBNService isbnServiceValue){idService = idServiceValue;nameService = nameServiceValue;isbnService = isbnServiceValue;SaveAsJsonFileCommand = new DelCommand(SaveAsJsonFileCommandExecuted);}private void SaveAsJsonFileCommandExecuted(object? obj){try{SaveFileDialog dialog = new SaveFileDialog();dialog.Filter = "Json File|*.json";dialog.FileName = $"Json_{DateTime.Now.ToString("yyyyMMddHHmmssffff")}";if (dialog.ShowDialog() == true){var dg = obj as DataGrid;var items = dg.Items.Cast<Book>()?.ToList();var jsonStr = JsonSerializer.Serialize(items,new JsonSerializerOptions(){WriteIndented = true});using (StreamWriter writer = new StreamWriter(dialog.FileName, true, Encoding.UTF8)){writer.WriteLine(jsonStr);}MessageBox.Show($"Saved in {dialog.FileName}");}}catch (Exception ex){MessageBox.Show(ex.Message);    }                      }public async Task InitBooksCollection(){BooksCollection = new ObservableCollection<Book>();List<Book> booksList = new List<Book>();for (int i = 1; i < 3000001; i++){booksList.Add(new Book(){Id = idService.GetID(),Name = nameService.GetName(),ISBN = isbnService.GetISBN(),Comment = $"Comment_{i}",Content = $"Content_{i}",Summary = $"Summary_{i}",Title = $"Title_{i}",Topic = $"Topic_{i}"});if (i % 1000000 == 0){var tempList = booksList.ToList();booksList.Clear();await Application.Current.Dispatcher.InvokeAsync(() =>{foreach (var book in tempList){BooksCollection.Add(book);}MainTitle = $"Now is {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}," +$"loaded {BooksCollection.Count} items";}, System.Windows.Threading.DispatcherPriority.Background);}}}public ICommand SaveAsJsonFileCommand { get; set;  }public event PropertyChangedEventHandler? PropertyChanged;private void OnPropertyChanged([CallerMemberName] string propertyName = ""){var handler = PropertyChanged;if (handler != null){handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));}}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 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);}}public interface IIDService{int GetID();}public class IDService : IIDService{int id = 0;public int GetID(){return Interlocked.Increment(ref id);}}public interface INameService{string GetName();}public class NameService : INameService{int idx = 0;public string GetName(){return $"Name_{Interlocked.Increment(ref idx)}";}}public interface IISBNService{string GetISBN();}public class ISBNService : IISBNService{int idx = 0;public string GetISBN(){return $"ISBN_{Interlocked.Increment(ref idx)}_{Guid.NewGuid():N}";}}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; }}
}

 

 

 

image

 

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

相关文章:

  • Android 源码解析系列1- Android init 进程启动流程
  • 英语_阅读_Start school_待读
  • 2025.10.20总结
  • 10.20总结
  • 学习相关
  • 题解:Luogu P2075 区间 LIS
  • 英语_阅读_2050 Space tourism_待读
  • goframe框架命令行工具gf在zsh下不能用
  • 题解:Luogu P10644 [NordicOI 2022] 能源网格 Power Grid
  • 题解:Luogu P10004 [集训队互测 2023] Permutation Counting 2
  • 题解:Luogu P4143 采集矿石
  • 从18w到1600w播放量,我的一点思考。
  • 扣一个细节问题
  • 10.20java作业
  • 题解:Luogu P14175 【MX-X23-T5】向死存魏
  • 软工第三次作业————结对作业
  • Spring 常见注解
  • 题解:AtCoder ARC208C Mod of XOR
  • 题解:Luogu P6898 [ICPC 2014 WF] Metal Processing Plant
  • 32-腾讯IM接入资料和定价
  • 题解:AtCoder ARC207A Affinity for Artifacts
  • 题解:Luogu P9260 [PA 2022] Miny
  • 题解:Luogu P13544 [OOI 2022] Serious Business
  • 题解:Luogu P14254 分割(divide)
  • 31_创蓝短信接入资料和定价
  • 02.Python百行代码实现抽奖系统
  • CSP-S 35
  • 题解:P11662 [JOI 2025 Final] 方格染色 / Grid Coloring
  • CSP-S 32 多校5
  • CSP-S 33