我有一个类 PlayerVM.cs ,它有一个属性:
public ObservableCollection<PlaylistVM> PlayLists
{
get { return _playLists; }
set { _playLists = value; }
}
PlaylistVM.cs 也有自己的集合:
public ObservableCollection<CompositionVM> Songs
{
get
{
return _songs;
}
set
{
_songs = value;
}
}
由此,我的PlayerVM有一个播放列表列表,每个播放列表都有自己的歌曲列表。 我需要显示按字母顺序排序的歌曲列表。但是我不想在ObservableCollections中更改它们的顺序,我只想在GUI中更改它们的顺序(只按字母顺序显示它们,而不是改变实际顺序)。 我是wpf(和xaml)的新手,今天我只学会了如何按字母顺序显示PLAYLISTS NAMES。我是通过代码来完成的:
<Window x:Class="Player_beta.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Player_beta">
<Window.Resources>
<CollectionViewSource Source="{Binding PlayLists}" x:Key="plView"><!--here I would like to get access to PlayLists.Songs-->
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="plNAME"/> <!--and here I would like to get NAME(that property of 'Songs' which contains songtitle) instead of plNAME - name of playlist)-->
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</Window.Resources>
<!-- etc...-->
<TreeView Name="treeCategories" ItemsSource="{Binding Source={StaticResource plView}}" >
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Songs}">
<TextBlock Text="{Binding plNAME}"/> <!-- <-- here is where the name of PLAYLIST shows-->
<HierarchicalDataTemplate.ItemTemplate >
<DataTemplate >
<TextBlock Text="{Binding NAME}"/> <!-- <-- here is where the name of song shows-->
</Grid>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
答案 0 :(得分:1)
您可以在PlaylistVM.cs类中添加 ICollectionView
实例并与其绑定。这样原始列表也不会受到影响。
private ICollectionView songsView;
public ICollectionView SongsView
{
get
{
if (songsView== null)
{
songsView= CollectionViewSource.GetDefaultView(Songs);
songsView.SortDescriptions.Add(new SortDescription("Name",
ListSortDirection.Ascending));
}
return songsView;
}
}
并在XAML中:
<HierarchicalDataTemplate ItemsSource="{Binding SongsView}">
答案 1 :(得分:1)
您可以做的是,您可以向CollectionView
类添加PlaylistVM
属性:
public CollectionView songsCollectionView;
public CollectionView SongsCollectionView
{
get
{
if (songsCollectionView == null)
{
songsCollectionView = new CollectionView(Songs);
songsCollectionView.SortDescriptions.Add(new SortDescription("plNAME", ListSortDirection.Ascending));
}
return songsCollectionView;
}
}
然后你可以像这样绑定你的xaml:
<HierarchicalDataTemplate ItemsSource="{Binding SongsCollectionView}">
这应满足您在GUI中显示已排序歌曲而无需更改原始集合的要求。
答案 2 :(得分:1)
这不是最有效的,但会完成工作。请注意,它不会检测任何歌曲的名称是否已更改。每次添加或删除歌曲时,它也会在UI中重建整个列表。
public class PlaylistVM: System.ComponentModel.INotifyPropertyChanged
{
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<CompositionVM> _songs;
public ObservableCollection<CompositionVM> Songs
{
get
{
return _songs;
}
set
{
if(_songs != value)
{
//if old value not null, unhook event
if (_songs != null)
{
_songs.CollectionChanged -= FireSongsChanged;
}
//change the value
_songs = value;
//if new value !=null, then attach handlers.
if (_songs != null)
{
_songs.CollectionChanged += FireSongsChanged;
}
//this will fire the
FireSongsChanged(null, null);
}
}
}
void FireSongsChanged(object sender, EventArgs e)
{
//the collection of songs has changed, tell UI that it needs to requery the list of ordered songs.
var ev = this.PropertyChanged;
if (ev != null)
{
ev(this, new System.ComponentModel.PropertyChangedEventArgs("OrderedSongs"));
}
}
//set the UI to bind to the following list of the songs. ordered by name.
public IEnumerable<CompositionVM> OrderedSongs
{
get
{
return Songs.OrderBy(song => song.Name);
}
}
}