Install-Package ZXing.Net
Install-Package Newtonsoft.Json
public static class QrCodeGenerator
{
public static BitmapImage GeneratorBookQrCode(Book bk, int width = 300, int height = 300)
{
if (bk == null)
{
throw new ArgumentException(nameof(bk), "bk can't be null");
}
string jsonStr = bk.ToJsonStr();
var writer = new BarcodeWriterPixelData
{
Format = BarcodeFormat.QR_CODE,
Options = new QrCodeEncodingOptions
{
Width = width,
Height = height,
Margin = 1,
CharacterSet = "UTF-8"
}
};
var pixelData = writer.Write(jsonStr);
using (var ms = new System.IO.MemoryStream())
{
var bitmap = new System.Drawing.Bitmap(pixelData.Width, pixelData.Height);
var bitmapData = bitmap.LockBits(
new System.Drawing.Rectangle(0, 0, pixelData.Width, pixelData.Height),
System.Drawing.Imaging.ImageLockMode.WriteOnly,
System.Drawing.Imaging.PixelFormat.Format32bppRgb);
try
{
System.Runtime.InteropServices.Marshal.Copy(pixelData.Pixels, 0, bitmapData.Scan0,
pixelData.Pixels.Length);
}
finally
{
bitmap.UnlockBits(bitmapData);
}
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
ms.Position = 0;
var bmpImg = new BitmapImage();
bmpImg.BeginInit();
bmpImg.CacheOption = BitmapCacheOption.OnLoad;
bmpImg.StreamSource = ms;
bmpImg.EndInit();
bmpImg.Freeze();
return bmpImg;
}
}
}
![image]()
![b8b6fb23c9402f0caccc0b8bdc451ee]()
![image]()
![2e74c12d287a55d63ac914ecb38950c]()
//xaml
<Window x:Class="WpfApp50.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:WpfApp50"
mc:Ignorable="d"
WindowState="Maximized"
Title="{Binding MainTitle}" Height="450" Width="800">
<Window.DataContext>
<local:MainVM/>
</Window.DataContext>
<Grid>
<DataGrid ItemsSource="{Binding BmiCollection}"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
VirtualizingPanel.CacheLength="2,2"
VirtualizingPanel.CacheLengthUnit="Item"
ScrollViewer.CanContentScroll="True"
ScrollViewer.IsDeferredScrollingEnabled="True"
CanUserAddRows="False"
AutoGenerateColumns="False"
ColumnWidth="*">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid Width="{Binding DataContext.GridWidth,RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
Height="{Binding DataContext.GridHeight,RelativeSource={RelativeSource AncestorType={x:Type Window}}}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="50"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="TextWrapping" Value="Wrap"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="FontSize" Value="80"/>
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<TextBlock Text="{Binding ISBN}" Grid.Column="0"/>
<Image Source="{Binding ImgSource}" Grid.Column="1"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
//cs
using Newtonsoft.Json;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
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 ZXing;
using ZXing.QrCode;
namespace WpfApp50
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Loaded += async (s, e) =>
{
var vm = this.DataContext as MainVM;
if (vm != null)
{
vm.GridWidth = this.ActualWidth;
vm.GridHeight = this.ActualHeight / 2;
await vm.InitBmiList();
}
};
}
}
public class MainVM : INotifyPropertyChanged
{
public MainVM()
{
BmiCollection = new ObservableCollection<BookModel>();
System.Timers.Timer tmr = new System.Timers.Timer();
tmr.Elapsed += Tmr_Elapsed;
tmr.Interval = 1000;
tmr.Start();
}
private string GetMemory()
{
var proc = Process.GetCurrentProcess();
return $"memory {proc.PrivateMemorySize64 / 1024 / 1024:F2} M";
}
private void Tmr_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
{
MainTitle = $"{DateTime.Now},loaded {BmiCollection.Count()} items, {GetMemory()}";
}
public async Task InitBmiList()
{
List<Book> booksList = new List<Book>();
await Task.Run(() =>
{
for (int i = 1; i < 10000001; i++)
{
var bk = new Book()
{
Id = i,
Name = $"Name_{i}",
ISBN = $"ISBN_{i}_{Guid.NewGuid():N}",
Content = $"Content_{i}",
Title = $"Title_{i}",
Topic = $"Topic_{i}"
};
var bmi = QrCodeGenerator.GeneratorBookQrCode(bk);
Application.Current?.Dispatcher?.InvokeAsync(() =>
{
BmiCollection.Add(new BookModel()
{
ISBN=bk.ISBN,
ImgSource=bmi
});
});
}
});
}
private string mainTitle;
public string MainTitle
{
get
{
return mainTitle;
}
set
{
if(value!=mainTitle)
{
mainTitle = value;
OnPropertyChanged(nameof(MainTitle));
}
}
}
private double gridHeight;
public double GridHeight
{
get
{
return gridHeight;
}
set
{
if (value != gridHeight)
{
gridHeight = value;
OnPropertyChanged(nameof(GridHeight));
}
}
}
private double gridWidth;
public double GridWidth
{
get
{
return gridWidth;
}
set
{
if (value != gridWidth)
{
gridWidth = value;
OnPropertyChanged(nameof(GridWidth));
}
}
}
private ObservableCollection<BookModel> bmiCollection;
public ObservableCollection<BookModel> BmiCollection
{
get
{
return bmiCollection;
}
set
{
if (value != bmiCollection)
{
bmiCollection = value;
OnPropertyChanged(nameof(BmiCollection));
}
}
}
public event PropertyChangedEventHandler? PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propName = "")
{
var handler = PropertyChanged;
if (handler != null)
{
handler?.Invoke(this, new PropertyChangedEventArgs(propName));
}
}
}
public class BookModel
{
public string ISBN { get; set; }
public ImageSource ImgSource { get; set; }
}
public class Book
{
public int Id { get; set; }
public string Name { get; set; }
public string ISBN { get; set; }
public string Content { get; set; }
public string Title { get; set; }
public string Topic { get; set; }
public string ToJsonStr()
{
return JsonConvert.SerializeObject(this, Formatting.Indented);
}
}
public static class QrCodeGenerator
{
public static BitmapImage GeneratorBookQrCode(Book bk, int width = 300, int height = 300)
{
if (bk == null)
{
throw new ArgumentException(nameof(bk), "bk can't be null");
}
string jsonStr = bk.ToJsonStr();
var writer = new BarcodeWriterPixelData
{
Format = BarcodeFormat.QR_CODE,
Options = new QrCodeEncodingOptions
{
Width = width,
Height = height,
Margin = 1,
CharacterSet = "UTF-8"
}
};
var pixelData = writer.Write(jsonStr);
using (var ms = new System.IO.MemoryStream())
{
var bitmap = new System.Drawing.Bitmap(pixelData.Width, pixelData.Height);
var bitmapData = bitmap.LockBits(
new System.Drawing.Rectangle(0, 0, pixelData.Width, pixelData.Height),
System.Drawing.Imaging.ImageLockMode.WriteOnly,
System.Drawing.Imaging.PixelFormat.Format32bppRgb);
try
{
System.Runtime.InteropServices.Marshal.Copy(pixelData.Pixels, 0, bitmapData.Scan0,
pixelData.Pixels.Length);
}
finally
{
bitmap.UnlockBits(bitmapData);
}
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
ms.Position = 0;
var bmpImg = new BitmapImage();
bmpImg.BeginInit();
bmpImg.CacheOption = BitmapCacheOption.OnLoad;
bmpImg.StreamSource = ms;
bmpImg.EndInit();
bmpImg.Freeze();
return bmpImg;
}
}
}
}