Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change list view sort Property / Direction within XAML only

I have a simple ListView and want to sort the contents numerically or alphabetically, ascending or descending. The choice comes from a drop down box. I understand I can use CollectionViewSource to achieve the sorting but how can I alter the SortDescription or direction on the fly?

Update:

Ok so I have setup my CVS like so, the viewModel is what the ListView is currently bound to. I require the PropertyName to be bound to the currently selected combo box item's property PropertyName. The combo box is bound to a custom list that expose the propertyname on which I want to sort.

It complains about the PropertyName that im attempting to use:

A 'Binding' cannot be set on the 'PropertyName' property of type 'SortDescription'. A 'Binding' can only be set on a DependencyProperty of a 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}}"  />
like image 575
Chris Avatar asked Nov 30 '11 19:11

Chris


1 Answers

you can this all at code behind in your 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

here is a little example for your view model

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

hope this helps

like image 145
punker76 Avatar answered Sep 21 '22 15:09

punker76