WPF ListBox ListView Datatemplate, parse xml to List via XmlSerializer and StringReader

[XmlRoot("ArrayOfBook", Namespace = "http://schemas.datacontract.org/2004/07/WcfService4")]
public class XmlBook
{
    [XmlElement(nameof(Book))]
    public List<Book> BksList { get; set; }
}

 private List<Book> DeserializeXmlStrToList(string xmlStr)
 {
     var xmlSerializer = new XmlSerializer(typeof(XmlBook));
     using (var reader = new StringReader(xmlStr))
     {
         var bks = (XmlBook)xmlSerializer.Deserialize(reader);
         return bks.BksList;
     }
 }

 

<Window x:Class="WpfApp8.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:WpfApp8"
        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="20"/>
            <Setter Property="FontWeight" Value="Normal"/>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Foreground" Value="Red"/>
                </Trigger>
            </Style.Triggers>
        </Style>

        <DataTemplate DataType="{x:Type local:Book}"
                      x:Key="BookDataTemplate">
            <Border BorderBrush="Cyan"
                    BorderThickness="1"
                    Margin="5">
                <Grid Margin="5">
                    <Grid.Resources>
                        <Style TargetType="TextBlock" BasedOn="{StaticResource TbkStyle}"/>
                    </Grid.Resources>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition MinWidth="100" SharedSizeGroup="Id"/>
                        <ColumnDefinition MinWidth="100" SharedSizeGroup="Name"/>
                        <ColumnDefinition Width="*" SharedSizeGroup="ISBN"/>
                        <ColumnDefinition MinWidth="100" SharedSizeGroup="Author"/>
                        <ColumnDefinition MinWidth="100" SharedSizeGroup="Comment"/>
                        <ColumnDefinition MinWidth="100" SharedSizeGroup="CategoryName"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Id}" Grid.Column="0"/>
                    <TextBlock Text="{Binding Name}" Grid.Column="1"/>
                    <TextBlock Text="{Binding ISBN}" Grid.Column="2"/>
                    <TextBlock Text="{Binding Author}" Grid.Column="3"/>
                    <TextBlock Text="{Binding Comment}" Grid.Column="4"/>
                    <TextBlock Text="{Binding CategoryName}" Grid.Column="5"/>
                </Grid>
            </Border>
        </DataTemplate>

        <ControlTemplate TargetType="ContentControl" x:Key="ContentControlTemplate">
            <ListBox Grid.IsSharedSizeScope="True"
                     ItemsSource="{Binding BksCollection}"
                     ItemTemplate="{StaticResource BookDataTemplate}"/>
        </ControlTemplate>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <GroupBox Header="ContentControlTemplate"
                  FontSize="30"
                  Grid.Row="0"
                  Margin="10"
                  BorderBrush="Blue"
                  BorderThickness="5">
            <ContentControl Template="{StaticResource ContentControlTemplate}"
                            Margin="5"/>
        </GroupBox>

        <GroupBox Header="ListBox"
                  FontSize="30"
                  Grid.Row="1"
                  Margin="10"
                  BorderBrush="Blue"
                  BorderThickness="5">
            <ListBox ItemsSource="{Binding BksCollection}" Grid.IsSharedSizeScope="True"
                     Margin="10">
                <ListBox.ItemTemplate>
                    <DataTemplate DataType="{x:Type local:Book}">
                        <Border BorderBrush="Cyan"
                     BorderThickness="1"
                     Margin="5">
                            <Grid>
                                <Grid.Resources>
                                    <Style TargetType="TextBlock" BasedOn="{StaticResource TbkStyle}"/>
                                </Grid.Resources>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition MinWidth="100" SharedSizeGroup="Id"/>
                                    <ColumnDefinition MinWidth="100" SharedSizeGroup="Name"/>
                                    <ColumnDefinition Width="*" SharedSizeGroup="ISBN"/>
                                    <ColumnDefinition MinWidth="100" SharedSizeGroup="Author"/>
                                    <ColumnDefinition MinWidth="100" SharedSizeGroup="Comment"/>
                                    <ColumnDefinition MinWidth="100" SharedSizeGroup="CategoryName"/>
                                </Grid.ColumnDefinitions>
                                <TextBlock Text="{Binding Id}" Grid.Column="0"/>
                                <TextBlock Text="{Binding Name}" Grid.Column="1"/>
                                <TextBlock Text="{Binding ISBN}" Grid.Column="2"/>
                                <TextBlock Text="{Binding Author}" Grid.Column="3"/>
                                <TextBlock Text="{Binding Comment}" Grid.Column="4"/>
                                <TextBlock Text="{Binding CategoryName}" Grid.Column="5"/>
                            </Grid>
                        </Border>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </GroupBox>

        <GroupBox Header="ListView"
                  Grid.Row="2"
                  FontSize="30"
                  BorderBrush="Blue"
                  BorderThickness="10">
            <ListView ItemsSource="{Binding BksCollection}">
                <ListView.Resources>
                    <Style TargetType="TextBlock" BasedOn="{StaticResource TbkStyle}"/>
                </ListView.Resources>
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="Id" DisplayMemberBinding="{Binding Id}" Width="Auto"/>
                        <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="Auto"/>
                        <GridViewColumn Header="ISBN" DisplayMemberBinding="{Binding ISBN}" Width="Auto"/>
                        <GridViewColumn Header="Author" DisplayMemberBinding="{Binding Author}" Width="100"/>
                        <GridViewColumn Header="Comment" DisplayMemberBinding="{Binding Comment}" Width="100"/>
                        <GridViewColumn Header="Category" DisplayMemberBinding="{Binding CategoryName}" Width="100"/>
                    </GridView>
                </ListView.View>
            </ListView>
        </GroupBox>
    </Grid>
</Window>


using System.Collections.ObjectModel;
using System.ComponentModel;
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 WpfApp8
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    public class MainVM : INotifyPropertyChanged
    {
        private static HttpClient client = new HttpClient();
        private static string originUrl = "http://localhost:64660/BookService.svc/getbooks?cnt=";

        public MainVM()
        {
            if(!DesignerProperties.GetIsInDesignMode(new DependencyObject()))
            {
                _ = InitBksAsync();
            }           
        }

        private async Task InitBksAsync(int cnt=10000)
        {
            string url = $"{originUrl}{cnt}";
            string xmlStr = await client.GetStringAsync(url);
            var bks = DeserializeXmlStrToList(xmlStr);
            BksCollection = new ObservableCollection<Book>(bks);
        }

        private List<Book> DeserializeXmlStrToList(string xmlStr)
        {
            var xmlSerializer = new XmlSerializer(typeof(XmlBook));
            using (var reader = new StringReader(xmlStr))
            {
                var bks = (XmlBook)xmlSerializer.Deserialize(reader);
                return bks.BksList;
            }
        }

        private ObservableCollection<Book> bksCollection;
        public ObservableCollection<Book> BksCollection
        {
            get
            {
                return bksCollection;
            }
            set
            {
                if (value != bksCollection)
                {
                    bksCollection = value;
                    OnPropertyChanged();
                }
            }
        }

        public event PropertyChangedEventHandler? PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            var handler = Volatile.Read(ref PropertyChanged);
            if (handler == null)
            {
                return;
            }
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    [XmlRoot("ArrayOfBook", Namespace = "http://schemas.datacontract.org/2004/07/WcfService4")]
    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 Author { get; set; }
        public string Comment { get; set; }
        public string CategoryName { get; set; }
    }
}

 

 

 

//WCF
//D:\C\WcfService4\WcfService4\IBookService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace WcfService4
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IBookService" in both code and config file together.
    [ServiceContract]
    public interface IBookService
    {
        [OperationContract]
        [WebGet(UriTemplate ="/getbooks?cnt={cnt}")]
        List<Book> GetBooks(int cnt=1000);
    }

    public class Book
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public string ISBN { get; set;  }
        public string Author { get; set;  }
        public string Comment { get; set;  }
        public string CategoryName { get; set; }
    }

    enum BookCategoryEnum
    {
        Science,
        Technology,
        Engineering,
        Math
    }
}


//D:\C\WcfService4\WcfService4\BookService.svc.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Threading;

namespace WcfService4
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "BookService" in code, svc and config file together.
    // NOTE: In order to launch WCF Test Client for testing this service, please select BookService.svc or BookService.svc.cs at the Solution Explorer and start debugging.
    public class BookService : IBookService
    {
        private static long id = 1;
        private static string[] enumNames = Enum.GetNames(typeof(BookCategoryEnum));
        private static int enumNamesCnt = enumNames.Length;
        private static Random rnd = new Random();
        private static (long, long) GetStartEnd(int cnt)
        {
            var end = Interlocked.Add(ref id, cnt);
            var start = end - cnt;
            return (start, end);
        }

        public List<Book> GetBooks(int cnt = 1000)
        {
            List<Book> bksList = new List<Book>();
            var (start, end) = GetStartEnd(cnt);
            for (long i = start; i < end; i++)
            {
                bksList.Add(new Book()
                {
                    Id = i,
                    Name = $"Name_{i}",
                    ISBN = $"ISBN_{i}_{Guid.NewGuid():N}",
                    Author = $"Author_{i}",
                    Comment = $"Comment_{i}",
                    CategoryName = $"{enumNames[rnd.Next(0, enumNamesCnt)]}"
                });
            }
            return bksList;
        }
    }
}


//D:\C\WcfService4\WcfService4\Web.config
<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
  </appSettings>
  <!--
    For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367.

    The following attributes can be set on the <httpRuntime> tag.
      <system.Web>
        <httpRuntime targetFramework="4.8.1" />
      </system.Web>
  -->
  <system.web>
    <compilation debug="true" targetFramework="4.8.1"/>
    <httpRuntime targetFramework="4.7.2"/>
  </system.web>
  <system.serviceModel>
      <bindings>
          <webHttpBinding>
              <binding name="BookServiceWebHttpBinding"
                       openTimeout="01:00:00"
                       closeTimeout="01:00:00"
                       sendTimeout="01:00:00"
                       receiveTimeout="01:00:00"
                       maxBufferPoolSize="2147483647"
                       maxBufferSize="2147483647"
                       maxReceivedMessageSize="2147483647">
                  <readerQuotas maxArrayLength="2147483647"
                                maxBytesPerRead="214748347"
                                maxDepth="2147483647"
                                maxNameTableCharCount="2147483647"
                                maxStringContentLength="2147483647"/>
                  <security mode="None"/>
              </binding>                        
          </webHttpBinding>
      </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="BookServiceBehavior">
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
        <endpointBehaviors>
            <behavior name="BookServiceEndPointBehavior">
                <webHttp/>
            </behavior>
        </endpointBehaviors>
    </behaviors>
    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https"/>
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
      <services>
          <service name="WcfService4.BookService"
                   behaviorConfiguration="BookServiceBehavior">
              <endpoint address=""
                        binding="webHttpBinding"
                        contract="WcfService4.IBookService"
                        behaviorConfiguration="BookServiceEndPointBehavior"
                        bindingConfiguration="BookServiceWebHttpBinding"/>
          </service>                   
      </services>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>
</configuration>

 

image

 

posted @ 2026-08-01 19:32  FredGrit  阅读(5)  评论(0)    收藏  举报