簡體   English   中英

我不能僅使用XAML對WPF ListBox進行排序

[英]I can not sort WPF ListBox using XAML only

我無法在XAML中對WPF ListBox進行排序。 我已經閱讀了如何僅使用XAML而不使用任何隱藏代碼對ListBox進行排序的文章? 但這並沒有幫助我。 我想按標題字段的升序對lbxBooks ListBox(顯示詳細數據,請參閱下面的XAML)進行排序。 此ListBox描述的是XAML:

<Window x:Class="BookCatalogue.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" WindowStartupLocation="CenterScreen">
    <Window.Resources>
        <!--This XMLDataProvider uses file Books.xml as data source 
        and executes (via XPath property) data query from Category nodes in this file.-->
        <XmlDataProvider x:Key="MyList" Source="Data\Books.xml"
                       XPath="Books/Category"/>
        <!--This is data template for ListBox that shows master-level data-->
        <DataTemplate x:Key="masterDataTemplate">
            <TextBlock Text="{Binding XPath=@name}" />
        </DataTemplate>
        <!--This is data template for ListBox that shows detail-level data-->
        <DataTemplate x:Key="detailDataTemplate">
          <StackPanel>
             <TextBlock Text="{Binding XPath=Cover}"/>
             <TextBlock Text="{Binding XPath=Title}" Margin="0,0,0,10"/>  <!--This is title of book-->
             <TextBlock Text="{Binding XPath=Author}" Margin="0,0,0,10"/>
             <TextBlock Text="{Binding XPath=Published}" Margin="0,0,0,10"/>
          </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <!--Grid for window mark up-->
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <!--This ListBox shows master-level data-->
      <ListBox Name="lbxCategory" Grid.Row="0" Grid.Column="0" ItemsSource="{Binding Source=
{StaticResource MyList}}"
                   ItemTemplate="{StaticResource masterDataTemplate}" 
IsSynchronizedWithCurrentItem="true"/>
        <!--This ListBox must show details-level data. It must be sorted by ascent by Title (title of the book)-->
      <ListBox Name="lbxBooks" Grid.Row="1" Grid.Column="0" ItemsSource="{Binding 
ElementName=lbxCategory, Path=SelectedItem.ChildNodes}"
               ItemTemplate="{StaticResource detailDataTemplate}" 
IsSynchronizedWithCurrentItem="True"/>
    </Grid>
</Window>

並且以下XML文件用作數據源。 “標題”節點在此處被注釋為“這是書名”:

<?xml version="1.0" encoding="utf-8" ?>
<Books xmlns="">
  <Category name="Computer Programming">
    <Book>
      <Author>H. Schildt</Author>
      <Title>C# 4.0 The Complete Reference</Title>  <!--This is title of book-->
      <Published>2011</Published>
      <Categ>Computer Programming</Categ>
    </Book>
    <Book>
      <Author>I. Abramson</Author>
      <Title>Oracle Database 10g. A Beginner's Guide</Title>  <!--This is title of book-->
      <Published>2004</Published>
      <Categ>Computer Programming</Categ>
    </Book>
  </Category>
  <Category name="Art Editions">
    <Book>
      <Author>M. Cervantes</Author>
      <Title>The Ingenious Gentleman Don Quixote of La Mancha </Title>  <!--This is title of book-->
      <Published>1997</Published>
      <Categ>Art Editions</Categ>
    </Book>
    <Book>
      <Author>P. Ronsard</Author>
      <Title>Les Amours</Title>
      <Published>1997</Published>
      <Categ>Art Editions</Categ>
    </Book>
  </Category>
</Books>

如何按標題(書名)的升序對lbxBooks ListBox進行排序。 我該怎么做?

這不是一個非常優雅的解決方案,但至少可以正常工作。 在您的Xaml中,添加綁定到書籍的另一個XmlDataProvider和用於過濾和排序的集合視圖。

這是您的Xaml:

<Window x:Class="BookCatalogue.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
        WindowStartupLocation="CenterScreen"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <!--This XMLDataProvider uses file Books.xml as data source 
        and executes (via XPath property) data query from Category nodes in this file.-->
        <XmlDataProvider x:Key="MyList" Source="Data\Books.xml" XPath="Books/Category"/>
        <XmlDataProvider x:Key="MySubList" Source="Data\Books.xml" XPath="Books/Category/Book"/>

        <!--This is data template for ListBox that shows master-level data-->
        <DataTemplate x:Key="masterDataTemplate">
            <TextBlock Text="{Binding XPath=@name}" />
        </DataTemplate>
        <!--This is data template for ListBox that shows detail-level data-->
        <DataTemplate x:Key="detailDataTemplate">
            <StackPanel>
                <TextBlock Text="{Binding XPath=Cover}"  Margin="0,0,0,2"/>
                <TextBlock Text="{Binding XPath=Title}" Margin="0,0,0,2"/>
                <!--This is title of book-->
                <TextBlock Text="{Binding XPath=Author}" Margin="0,0,0,2"/>
                <TextBlock Text="{Binding XPath=Published}" Margin="0,0,0,10"/>
            </StackPanel>
        </DataTemplate>

        <CollectionViewSource x:Key="SortedList" Source="{StaticResource MySubList}" Filter="CollectionViewSource_Filter_1" IsLiveFilteringRequested="True">
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="Title"/>
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>

    </Window.Resources>
    <!--Grid for window mark up-->
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <!--This ListBox shows master-level data-->
        <ListBox Name="lbxCategory" Grid.Row="0" Grid.Column="0" 
                 ItemsSource="{Binding Source={StaticResource MyList}}"
                 ItemTemplate="{StaticResource masterDataTemplate}" 
                 IsSynchronizedWithCurrentItem="true" 
                 SelectionChanged="lbxCategory_SelectionChanged_1"/>

        <!--This ListBox must show details-level data. It must be sorted by ascent by Title (title of the book)-->
        <ListBox Name="lbxBooks" Grid.Row="1" Grid.Column="0" 
               ItemsSource="{Binding Source={StaticResource SortedList}}"
               ItemTemplate="{StaticResource detailDataTemplate}" 
               IsSynchronizedWithCurrentItem="True"/>

    </Grid>
</Window>

並將這些方法添加到您的代碼后面。

private void lbxCategory_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
    lbxBooks.Items.Refresh();
    CollectionViewSource collectionView = Resources["SortedList"] as CollectionViewSource;
    if(collectionView.View != null) collectionView.View.Refresh();
}

private void CollectionViewSource_Filter_1(object sender, FilterEventArgs e)
{
    XmlElement element = e.Item as XmlElement;
    e.Accepted = ((XmlElement)lbxCategory.SelectedItem).Attributes["name"].Value == element.ParentNode.Attributes["name"].Value;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM