我有一个简单的ListView
,想要按数字或字母顺序,升序或降序对内容进行排序。选择来自下拉框。我知道我可以使用CollectionViewSource
来实现排序,但是如何动态改变SortDescription或方向?
更新
好的,所以我设置了我的CVS,viewModel就是ListView当前绑定的内容。我要求PropertyName绑定到当前选定的组合框项的属性PropertyName
。组合框绑定到一个自定义列表,该列表显示我要对其进行排序的属性名称。
它抱怨我尝试使用的PropertyName:
无法在类型的'PropertyName'属性上设置'绑定' 'SortDescription'。 '绑定'只能在DependencyProperty上设置 DependencyObject。
<CollectionViewSource Source="{StaticResource viewModel.ListValues}" x:Key="cvs">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="{Binding Path=SortPropertyName, Source=comboSort}"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
<ListView ItemsSource="{Binding Source={StaticResource cvs}}" />
答案 0 :(得分:4)
你可以在viewmodel
中使用代码// in your view model
private void ChangeSorting () {
var collView = CollectionViewSource.GetDefaultView(ListValues);
collView.SortDescriptions.Clear();
// do this one
collView.SortDescriptions.Add(new SortDescription("YourPropertyName", ListSortDirection.Ascending));
// or this one
collView.SortDescriptions.Add(new SortDescription("YourOtherPropertyName", ListSortDirection.Descending));
collView.Refresh();
}
public ICollectionView ListValuesCollectionViewSource
{
get {
return collView;
}
}
<ListView ItemsSource="{Binding viewModel.ListValuesCollectionViewSource}" />
修改强>
这是您的视图模型的一个小例子
<ComboBox ItemsSource="{Binding viewmodel.YourDataForComboboxCollection, Mode=OneWay}"
SelectedItem="{Binding viewmodel.SelectedCombobox}" />
一个小视图模型
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;
namespace YourNameSpace
{
public class ViewModel : INotifyPropertyChanged
{
public static readonly DependencyProperty SelectedComboboxProperty =
DependencyProperty.Register("SelectedCombobox", typeof(YourDataForCombobox), typeof(ViewModel), new PropertyMetadata(default(YourDataForCombobox), new PropertyChangedCallback(SelectedComboboxCallback)));
private static void SelectedComboboxCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) {
var vm = sender as ViewModel;
if (vm != null && e.NewValue != null && e.NewValue != e.OldValue) {
vm.ChangeSorting(e.NewValue);
}
}
public ViewModel() {
this.YourDataForComboboxCollection = new ObservableCollection<YourDataForCombobox>();
}
private void ChangeSorting(YourDataForCombobox newValue) {
this.yourCollectionView.SortDescriptions.Clear();
this.yourCollectionView.SortDescriptions.Add(new SortDescription(newValue.PropertyName, newValue.Sorting));
this.yourCollectionView.Refresh();
}
private IObservableCollection yourDataForComboboxCollection;
public IObservableCollection YourDataForComboboxCollection {
get { return this.yourDataForComboboxCollection; }
set {
this.yourDataForComboboxCollection = value;
this.RaisePropertyChanged("YourDataForComboboxCollection");
}
}
public YourDataForCombobox SelectedCombobox {
get { return (YourDataForCombobox)GetValue(SelectedComboboxProperty); }
set { SetValue(SelectedComboboxProperty, value); }
}
private IObservableCollection yourCollection;
private ICollectionView yourCollectionView;
public ICollectionView YourCollectionView {
get { return this.GetCollectionView(); }
}
private ICollectionView GetCollectionView() {
if (this.yourCollection == null) {
this.yourCollection = new ObservableCollection<YourDataForCollection>();
this.yourCollectionView = CollectionViewSource.GetDefaultView(this.yourCollection);
// initial sorting
this.ChangeSorting(null);
}
return this.yourCollectionView;
}
private void RaisePropertyChanged(string property) {
var eh = this.PropertyChanged;
if (eh != null) {
eh(this, new PropertyChangedEventArgs(property));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
希望这会有所帮助
答案 1 :(得分:2)
您还可以将其置于行为中,添加另一个要绑定的属性以动态设置排序描述方向,但此解决方案仅适用于按一个属性排序。它当然可以扩展到更多的工作。
XAML:
<CollectionViewSource x:Key="GroupedMeetingItems" Source="{Binding Items}" util:CollectionViewSourceBehavior.IsAscending="{Binding IsItemsAscending}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="StartDateTime" Converter="{StaticResource DateTimeToDisplayDateConverter}" />
</CollectionViewSource.GroupDescriptions>
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="StartDateTime" Direction="Descending"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
行为:
public static class CollectionViewSourceBehavior
{
public static readonly DependencyProperty IsAscendingProperty =
DependencyProperty.RegisterAttached(
"IsAscending",
typeof(bool),
typeof(CollectionViewSourceBehavior),
new UIPropertyMetadata(false, OnIsAscendingChanged));
public static object GetIsAscending(FrameworkElement element)
{
return element.GetValue(IsAscendingProperty);
}
public static void SetIsAscending(FrameworkElement element, object value)
{
element.SetValue(IsAscendingProperty, value);
}
public static void OnIsAscendingChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var collectionViewSource = dependencyObject as CollectionViewSource;
if (collectionViewSource == null)
{
return;
}
var isAscending = e.NewValue as bool? == true;
var newSortDescription = new SortDescription
{
Direction = isAscending ? ListSortDirection.Ascending : ListSortDirection.Descending,
PropertyName = collectionViewSource.SortDescriptions.FirstOrDefault().PropertyName
};
collectionViewSource.SortDescriptions.Clear();
collectionViewSource.SortDescriptions.Add(newSortDescription);
}
}