//This XML file does not appear to have any style information associated with it. The document tree is shown below.
<ArrayOfBook xmlns="http://schemas.datacontract.org/2004/07/WcfService3" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Book>
<CategoryName>Engineering</CategoryName>
<Comment>Comment_4020611</Comment>
<ISBN>ISBN_4020611_873618a856b04c7186dbe2a60eb0a218</ISBN>
<Id>4020611</Id>
<Name>Name_4020611</Name>
</Book>
<Book>
<CategoryName>Engineering</CategoryName>
<Comment>Comment_4020612</Comment>
<ISBN>ISBN_4020612_bf13765c127042f99615207c5fd00953</ISBN>
<Id>4020612</Id>
<Name>Name_4020612</Name>
</Book>
</ArrayOfBook>
![image]()
public class Book
{
public long Id { get; set; }
public string Name { get; set; }
public string ISBN { get; set; }
public string Comment { get; set; }
public string CategoryName { get; set; }
}
[XmlRoot("ArrayOfBook", Namespace = "http://schemas.datacontract.org/2004/07/WcfService3")]
public class XmlBook
{
[XmlElement(nameof(Book))]
public List<Book> BksList { get; set; }
}
private List<Book> XmlSerializerDeserializeXmlStr(string xmlStr)
{
var serializer = new XmlSerializer(typeof(XmlBook));
using (var reader = new StringReader(xmlStr))
{
var xmlBook = (XmlBook)serializer.Deserialize(reader);
if (xmlBook != null && xmlBook.BksList != null && xmlBook.BksList.Any())
{
return xmlBook.BksList;
}
}
return null;
}
//xaml
<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"
Title="MainWindow"
WindowState="Maximized">
<Window.DataContext>
<local:MainVM/>
</Window.DataContext>
<Window.Resources>
<Style TargetType="TextBlock" x:Key="TbkStyle">
<Setter Property="FontSize" Value="30"/>
<Setter Property="FontWeight" Value="Normal"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="FontWeight" Value="Bold"/>
</Trigger>
</Style.Triggers>
</Style>
<DataTemplate DataType="{x:Type local:Book}"
x:Key="RowDataTemplate">
<Border BorderBrush="LightGray"
BorderThickness="1"
Margin="3">
<Grid Margin="3">
<Grid.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource TbkStyle}"/>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Id}" Grid.Row="0" Grid.Column="0"/>
<TextBlock Text="{Binding Name}" Grid.Row="0" Grid.Column="1"/>
<TextBlock Text="{Binding CategoryName}" Grid.Row="1" Grid.Column="0"/>
<TextBlock Text="{Binding Comment}" Grid.Row="1" Grid.Column="1"/>
<TextBlock Text="{Binding ISBN}" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2"/>
</Grid>
</Border>
</DataTemplate>
<ControlTemplate TargetType="ContentControl" x:Key="ContentControlTemplate">
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Books}"
ItemTemplate="{StaticResource RowDataTemplate}"
Margin="5"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
VirtualizingPanel.CacheLength="5,5"
VirtualizingPanel.CacheLengthUnit="Item"
ScrollViewer.CanContentScroll="True"
ScrollViewer.IsDeferredScrollingEnabled="True"
UseLayoutRounding="True"
SnapsToDevicePixels="True">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
</ControlTemplate>
</Window.Resources>
<Grid>
<ContentControl Template="{StaticResource ContentControlTemplate}"/>
</Grid>
</Window>
//cs
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
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;
using System.Xml.Serialization;
namespace WpfApp6
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Closed += MainWindow_Closed;
}
private void MainWindow_Closed(object? sender, EventArgs e)
{
var vm = this.DataContext as MainVM;
if(vm!=null)
{
vm.Dispose();
}
}
}
public class MainVM : INotifyPropertyChanged, IDisposable
{
private bool _isDisposed = false;
private CancellationTokenSource _cts = new CancellationTokenSource();
private Task _loadTask;
private string originUrl = "http://localhost:57995/BookService.svc/getbooks?cnt=";
private HttpClient client = new HttpClient();
public MainVM()
{
if (!DesignerProperties.GetIsInDesignMode(new DependencyObject()))
{
_loadTask = LoadDataAsync(100, _cts.Token);
}
}
private async Task LoadDataAsync(int cnt = 10000, CancellationToken token = default)
{
if (_cts.IsCancellationRequested)
{
return;
}
try
{
string url = $"{originUrl}{cnt}";
string xmlStr = await client.GetStringAsync(url);
var bksList = XmlSerializerDeserializeXmlStr(xmlStr);
if (bksList != null && bksList.Any())
{
if(token.IsCancellationRequested)
{
return;
}
await Application.Current?.Dispatcher?.InvokeAsync(() =>
{
Books = new ObservableCollection<Book>(bksList);
}, System.Windows.Threading.DispatcherPriority.Background);
}
}
catch (Exception ex)
{
MessageBox.Show(ex?.Message);
return;
}
}
private ObservableCollection<Book> books;
public ObservableCollection<Book> Books
{
get
{
return books;
}
set
{
if (value != books)
{
books = 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 void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool isDisposing)
{
if (_isDisposed)
{
return;
}
if (isDisposing)
{
_cts = null;
client = null;
_isDisposed = true;
}
}
private List<Book> XmlSerializerDeserializeXmlStr(string xmlStr)
{
var serializer = new XmlSerializer(typeof(XmlBook));
using (var reader = new StringReader(xmlStr))
{
var xmlBook = (XmlBook)serializer.Deserialize(reader);
if (xmlBook != null && xmlBook.BksList != null && xmlBook.BksList.Any())
{
return xmlBook.BksList;
}
}
return null;
}
}
[XmlRoot("ArrayOfBook", Namespace = "http://schemas.datacontract.org/2004/07/WcfService3")]
public class XmlBook
{
[XmlElement(nameof(Book))]
public List<Book> BksList { get; set; }
}
public class Book
{
public long Id { get; set; }
public string Name { get; set; }
public string ISBN { get; set; }
public string Comment { get; set; }
public string CategoryName { get; set; }
}
}
![image]()
![image]()