2011-11-30 19 views
5

Basit bir ListView var ve içerikleri sayısal veya alfabetik olarak artan veya azalan şekilde sıralamak istiyorum. Seçim bir açılır kutudan gelir. Anlamak için CollectionViewSource'u kullanabilirim ama SortDescription'ı veya yönünü nasıl değiştirebilirim?Liste görünümü sırala XAML içinde Özellik/Yön sadece

Güncelleme: Öyle gibi benim CVS, ViewModel ListView şu anda bağlı olduğu şeydir kurulum var bu yüzden

Ok. PropertyName öğesinin şu anda seçili açılan kutu öğesinin PropertyName özelliğine bağlı olmasını şart koşuyorum. Birleşik kutu, sıralamak istediğim propertyname öğesini gösteren özel bir listeye bağlanır. Bu kullanmaya çalışırken im PropertyName şikayetçi

:

A 'Bağlama' türü 'SortDescription' arasında 'PropertyName' mülkiyet ayarlanamaz. Bir 'Bağlama' yalnızca bir DependencyObject öğesinin DependencyProperty üzerinde ayarlanabilir.

<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

sonra (farklı karşılaştırıcısı ile) yeni sıralama açıklama eklemek eski tür tanımını kaldırmak ve nihayet istediğim CollectionViewSource – punker76

+0

yenile çağırabilir Bunu sadece XAML'de yapmak için, yani kodun hiçbiri (ViewModel'de kod kabul edilebilirdir) – Chris

+0

evet o zaman yapın, açılır kutunuz viewmodel'inizdeki bir özelliğe bağlanır ve seçiminizi değiştirdikten sonra CollectionViewSource'unuzu değiştirebilirsiniz. w CollectionViewSource'a bağlanır) – punker76

cevap

2

yapabilirsiniz

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

burada DÜZENLEME

görünümünüzü modeline

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

bir için biraz örnektir tüm ViewModel arkasında koda bu küçük vie 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; 
    } 
} 

umut bu dinamik sıralama açıklaması yönünü ayarlamak için bağlamak için başka bir özellik ekleyerek

+0

CVS'yi güncellemek için ViewModel'deki açılan kutu değişikliğini nasıl algılarım? – Chris

+0

düzenlenmiş cevaba bakın, umarım bu yardımcı olur – punker76

2

Ayrıca davranış içine koyabilirsiniz yardımcı olur, ancak bu çözüm sadece bir özelliğe göre sıralama için çalışır. Daha fazla çalışmak için kesinlikle genişletilebilir.

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> 

Davranış:

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