我无法在XAML中对WPF ListBox进行排序。我看过帖子了 How can I sort a ListBox using only XAML and no code-behind?但它没有帮助我。我想通过Title字段上升来对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排序。我该怎么办?
答案 0 :(得分:1)
不是一个非常优雅的解决方案,但至少它有效。在您的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;
}