Изменить вид списка сортировка Свойство / Направление только в XAML - PullRequest
6 голосов
/ 30 ноября 2011

У меня есть простой ListView и я хочу отсортировать содержимое по номерам или по алфавиту, по возрастанию или по убыванию.Выбор происходит из выпадающего списка.Я понимаю, что могу использовать CollectionViewSource для выполнения сортировки, но как я могу изменить SortDescription или направление на лету?

Обновление:

Хорошо, поэтому у меня есть настройкимой CVS вроде так, viewModel - это то, к чему в настоящее время привязан ListView.Я требую, чтобы PropertyName был привязан к выбранному в данный момент свойству элемента со списком PropertyName.Поле со списком привязано к пользовательскому списку, который отображает имя свойства, по которому я хочу отсортировать.

Он жалуется на PropertyName, который я пытаюсь использовать:

A 'Binding'не может быть установлено в свойстве «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}}"  />

Ответы [ 2 ]

4 голосов
/ 30 ноября 2011

Вы можете все это в коде позади в вашей 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}"  />

EDIT

вот небольшой пример для вашей модели взгляда

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

надеюсь, это поможет

2 голосов
/ 22 мая 2013

Вы также можете поместить это в поведение, добавив другое свойство для привязки, чтобы динамически установить направление описания сортировки, но это решение работает только для сортировки по одному свойству. Это, безусловно, можно расширить, чтобы работать больше.

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