仅在XAML中更改列表视图排序属性/方向



我有一个简单的ListView,并希望按数字或字母顺序,升序或降序对内容进行排序。选择来自一个下拉框。我知道我可以使用CollectionViewSource来实现排序,但是我如何在飞行中改变SortDescription或方向?

更新:

我已经像这样设置了CVS, viewModel是ListView当前绑定的。我需要PropertyName绑定到当前选择的组合框项目的属性PropertyName。组合框绑定到一个自定义列表,该列表公开了我想要排序的属性名。

它抱怨我试图使用的PropertyName:

'Binding'不能在type的'PropertyName'属性上设置"SortDescription"。"绑定"只能在DependencyProperty上设置

    <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}}"  />

你可以在你的视图模型后面的代码

// 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}" />

a little viewmodel

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;
  }
}

希望能有所帮助

您还可以将其放入行为中,添加另一个要绑定的属性以动态设置排序描述方向,但此解决方案仅适用于按一个属性排序。它当然可以扩展到更多的工作。

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);
    }
}

最新更新