2009-06-18 20 views
11

ObservableCollection<T> ürünüm var. ListBox denetimine bağladım ve liste sıralamasını nasıl yapmak istediğimi yapmak için ListBox'taki Öğeler koleksiyonuna SortDescriptions ekledim.Gözlemlenebilir Koleksiyon Varlık Toplamadaki Öğede Değiştirildi

Bir alt öğe üzerinde herhangi bir özellik değiştirildiğinde, listeye ANY noktasında başvurmak istiyorum. Tüm öğelerim INotifyPropertyChanged'u uygular.

+0

Yani, bir liste kutusu için OC bağlayıcı ve liste üzerinde sortdescription var mı? – apandit

+0

Bu doğru. Bir alt öğenin bir özelliği değiştirildiğinde, bu değişikliğin bu tür yansımaları olmasını isterim. – Nate

cevap

12

kaba kuvvet:

  1. sizin CollectionViewSource
  2. Çağrı Yenile gelen her çocuk öğesi
  3. tut ListCollectionView için her PropertyChanged olay işleyicisi ekleyin.

DÜZENLEME:

kod 1 için, 2 sizin kod arkada yaşayacaktı.

1. için, böyle bir şey yapmak istiyorum:

private void Source_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
{ 
    switch (e.Action) 
    { 
     case NotifyCollectionChangedAction.Add: 
      foreach(SomeItem item in e.NewItems) 
      { 
       item.PropertyChanged += new PropertyChangedEventHandler(_SomeItem_PropertyChanged); 
      } 
      break; 
.... 
**HANDLE OTHER CASES HERE** 
.... 
     } 
} 

# 2 için, CollectionChanged işleyicisinde, sen böyle bir şey yapsın:

private void _SomeItem_PropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    ListCollectionView lcv = (ListCollectionView)(CollectionViewSource.GetDefaultView(theListBox.ItemsSource)); 
    lcv.Refresh(); 
} 

EDIT2: Ancak içinde Bu durumda, güçlü bir şekilde olmasını, ListCollectionView.NeedsRefresh öğelerini de kontrol etmenizi ve yalnızca ayarlanmışsa yenilemenizi öneririm. Mülkleriniz değiştiyse, yeniden sıralama yapmak için bir neden yok.

+0

Bu kod sunum katmanımda yaşıyor muyum? Window.Xaml.Cs? # 1 ve # 2 kodları nasıl görünür? – Nate

+0

Tam olarak ihtiyacım olan şey bu. Sadece ikinci bölümü kullanarak bitti, çünkü benim durumumda değişikliğe neden olan bir olayım var, bu yüzden sadece 2'ye ihtiyacım vardı. – Nate

0

Bu çalışır. Koleksiyon her değiştiğinde, koleksiyonu yeniden sıralar. Daha verimli bir şekilde yapılabilir, ancak bu onun özüdür.

 

public partial class TestWindow : Window { 
     ObservableCollection<TestClass> oc; 
     public TestWindow() { 
      InitializeComponent(); 
      // Fill in the OC for testing 
      oc = new ObservableCollection<TestClass>(); 
      foreach(char c in "abcdefghieeddjko") { 
       oc.Add(new TestClass(c.ToString(), c.ToString(), c.GetHashCode())); 
      } 

      lstbox.ItemsSource = oc; 
      // Set up the sorting (this is how you did it.. doesn't work) 
      lstbox.Items.SortDescriptions.Add(new SortDescription("A", ListSortDirection.Ascending)); 
      // This is how we're going to do it 
      oc.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(oc_Sort); 
     } 

     void oc_Sort(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { 
      // This sorts the oc and returns IEnumerable 
      var items = oc.OrderBy<TestClass, int>((x) => (x.C)); 
      // Rest converst IEnumerable back to OC and assigns it 
      ObservableCollection<TestClass> temp = new ObservableCollection<TestClass>(); 
      foreach(var item in items) { 
       temp.Add(item); 
      } 
      oc = temp; 
     } 

     private void Button_Click(object sender, RoutedEventArgs e) { 
      string a = "grrrr"; 
      string b = "ddddd"; 
      int c = 383857; 
      oc.Add(new TestClass(a, b, c)); 
     } 


    } 

    public class TestClass : INotifyPropertyChanged { 
     private string a; 
     private string b; 
     private int c; 

     public TestClass(string f, string g, int i) { 
      a = f; 
      b = g; 
      c = i; 
     } 
     public string A { 
      get { return a; } 
      set { a = value; OnPropertyChanged("A"); } 
     } 
     public string B { 
      get { return b; } 
      set { b = value; OnPropertyChanged("B"); } 
     } 
     public int C { 
      get { return c; } 
      set { c = value; OnPropertyChanged("C"); } 
     } 

     #region onpropertychanged 

     public event PropertyChangedEventHandler PropertyChanged; 
     protected void OnPropertyChanged(string propertyName) { 
      if(this.PropertyChanged != null) { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
     #endregion 
    } 
 

XAML:

 
<Window x:Class="ServiceManager.TestWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="TestWindow" Height="500" Width="500"> 
    <DockPanel> 
     <ListBox ItemsSource="{Binding}" x:Name="lstbox"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal"> 
         <Label Content="{Binding Path=A}"/> 
         <Label Content="{Binding Path=B}"/> 
         <Label Content="{Binding Path=C}"/> 
        </StackPanel> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 
     <Button Click="Button_Click" Content="Click" /> 
    </DockPanel> 
</Window> 
+2

GözlemlenebilirKoleksiyon , öğelerinde PropertyChanged olaylarını dinlemez; bu nedenle, öğelerin bir özelliği değiştirildiğinde, bu yeniden sıralamada başarısız olur. http://msdn.microsoft.com/en-us/magazine/dd252944.aspx – Odrade

İlgili konular