8

我有一个简单的ListView,想按数字或字母顺序,升序或降序对内容进行排序。选择来自下拉框。我知道我可以使用它CollectionViewSource来实现排序,但我怎样才能动态更改 SortDescription 或方向?

更新:

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

它抱怨我试图使用的 PropertyName:

不能在“SortDescription”类型的“PropertyName”属性上设置“绑定”。只能在 DependencyObject 的 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}}"  />
4

2 回答 2

5

你可以在你的视图模型后面的代码中完成这一切

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

希望这可以帮助

于 2011-11-30T19:40:40.343 回答
5

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

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);
    }
}
于 2013-05-22T18:34:04.083 回答