


























<Window x:Class="WpfApp6.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:WpfApp6" mc:Ignorable="d" WindowState="Maximized" Title="{Binding MainTitle}" Height="450" Width="800"> <Window.DataContext> <local:MainVM/> </Window.DataContext> <Window.Resources> <local:ImgUrlConveter x:Key="ImgUrlConveter"/> </Window.Resources> <Grid> <ListBox ItemsSource="{Binding BooksCollection}" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling" ScrollViewer.CanContentScroll="True" ScrollViewer.IsDeferredScrollingEnabled="True" ScrollViewer.VerticalScrollBarVisibility="Visible"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel/> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBox.ItemTemplate> <DataTemplate> <Grid Width="{Binding DataContext.GridWidth,RelativeSource={RelativeSource AncestorType=Window}}" Height="{Binding DataContext.GridHeight,RelativeSource={RelativeSource AncestorType=Window}}"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <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="50"/> </Trigger> </Style.Triggers> </Style> </Grid.Resources> <Grid.Background> <ImageBrush ImageSource="{Binding ImgUrl,Converter={StaticResource ImgUrlConveter}}" Stretch="Uniform"/> </Grid.Background> <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> </ListBox.ItemTemplate> </ListBox> </Grid> </Window> using System.Collections.ObjectModel; using System.ComponentModel; 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 WpfApp6 { /// <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) { var fe = this.Content as FrameworkElement; if (fe != null) { vm.GridWidth = fe.ActualWidth; vm.GridHeight = fe.ActualHeight; } await vm.InitBooksCollection(50099991); } }; } } public class MainVM : INotifyPropertyChanged { public async Task InitBooksCollection(int cnt = 10000000) { var imgDir = @"../../../Images"; if (!Directory.Exists(imgDir)) { return; } var imgs = Directory.GetFiles(imgDir); if (imgs == null || !imgs.Any()) { return; } int imgsCount = imgs.Count(); BooksCollection = new ObservableCollection<Book>(); List<Book> bksList = new List<Book>(); for (int i = 1; i < cnt + 1; i++) { bksList.Add(new Book() { Id = i, Name = $"Name_{i}", ISBN = $"ISBN_{i}_{Guid.NewGuid():N}", Topic = $"Topic_{i}", ImgUrl = imgs[i % imgsCount] }); if (i % 500000 == 0) { var tempList = bksList.ToList(); bksList.Clear(); await PopulateBooksCollectionAsync(tempList); } } if (bksList.Any()) { await PopulateBooksCollectionAsync(bksList); bksList.Clear(); } } private string GetMem() { return $"{System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64 / 1024 / 1024:F2} M"; } private async Task PopulateBooksCollectionAsync(List<Book> tempList) { await Application.Current.Dispatcher.InvokeAsync(() => { foreach (var bk in tempList) { BooksCollection.Add(bk); } MainTitle = $"{DateTime.Now} loaded {BooksCollection.Count} books,{GetMem()}"; },System.Windows.Threading.DispatcherPriority.Background); } private ObservableCollection<Book> booksCollection; public ObservableCollection<Book> BooksCollection { get { return booksCollection; } set { if (value != booksCollection) { booksCollection = value; OnPropertyChanged(); } } } private double gridHeight; public double GridHeight { get { return gridHeight; } set { if (value != gridHeight) { gridHeight = value; OnPropertyChanged(); } } } private double gridWidth; public double GridWidth { get { return gridWidth; } set { if (value != gridWidth) { gridWidth = value; OnPropertyChanged(); } } } private string mainTitle = ""; public string MainTitle { get { return mainTitle; } set { if (value != mainTitle) { mainTitle = value; OnPropertyChanged(); } } } public event PropertyChangedEventHandler? PropertyChanged; private void OnPropertyChanged([CallerMemberName] string propName = "") { var handler = PropertyChanged; if (handler != null) { handler?.Invoke(this, new PropertyChangedEventArgs(propName)); } } } public class ImgUrlConveter : IValueConverter { Dictionary<string, ImageSource> imgCache = new Dictionary<string, ImageSource>(); public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { string imgUrl = value?.ToString(); if (!string.IsNullOrWhiteSpace(imgUrl) && File.Exists(imgUrl)) { if (imgCache.TryGetValue(imgUrl, out ImageSource? imageSource)) { return imageSource; } BitmapImage bmi = new BitmapImage(); bmi.BeginInit(); bmi.UriSource = new Uri(imgUrl, UriKind.RelativeOrAbsolute); bmi.CacheOption = BitmapCacheOption.OnLoad; bmi.EndInit(); if (bmi.CanFreeze) { bmi.Freeze(); } imgCache[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; } } }


此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。