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]()