2011-11-30 12 views
5

Ho un semplice ListView e desidero ordinare i contenuti in ordine numerico o alfabetico, in ordine crescente o decrescente. La scelta viene da un menu a tendina. Capisco che posso usare CollectionViewSource per raggiungere l'ordinamento, ma come posso modificare SortDescription o direzione al volo?Cambia visualizzazione elenco ordina Proprietà/Direzione solo XAML

Aggiornamento:

Ok, quindi ho installato i miei CVS come così, il ViewModel è ciò che il ListView è al momento legato. Richiedo che PropertyName sia associato alla proprietà dell'articolo della casella combinata attualmente selezionata PropertyName. La casella combinata è associata a un elenco personalizzato che espone il nome proprietà su cui voglio ordinare.

Si lamenta il PropertyName che im tentare di utilizzare:

A 'vincolante' non può essere impostato sulla proprietà 'PropertyName' di tipo 'SortDescription'. Un 'Binding' può essere impostato solo su DependencyProperty di 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

è possibile rimuovere la vecchia descrizione sorta quindi aggiungere la nuova descrizione ordinamento (con il diverso di confronto) ed infine chiamare aggiornamento sulla CollectionViewSource – punker76

+0

voglio per fare questo solo in XAML, cioè senza codice (il codice in ViewModel è accettabile) – Chris

+0

sì, poi lo fai, il tuo menu a tendina si lega a una proprietà sul tuo viewmodel e dopo aver cambiato la selezione puoi cambiare la tua CollectionViewSource (la tua lista w si collega alla CollectionViewSource) – punker76

risposta

2

è possibile tutto questo in codice dietro nel vostro 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

ecco un piccolo esempio per la vostra vista del modello

<ComboBox ItemsSource="{Binding viewmodel.YourDataForComboboxCollection, Mode=OneWay}" 
      SelectedItem="{Binding viewmodel.SelectedCombobox}" /> 

un piccola vita wmodel

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

speranza che questo aiuta

+0

Come posso rilevare la modifica della casella combinata nel ViewModel per aggiornare il CVS? – Chris

+0

guarda la risposta modificata, spero che questo aiuti – punker76

2

si può anche mettere questo in un comportamento, aggiungendo un'altra proprietà di legarsi per impostare dinamicamente la descrizione Direzione di ordinamento, ma questa soluzione funziona solo per l'ordinamento per una proprietà. Potrebbe certamente essere ampliato per lavorare di più.

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> 

Comportamento:

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