2009-06-18 21 views
11

मेरे पास ObservableCollection<T> है। मैंने इसे एक सूची बॉक्स नियंत्रण में बाध्य कर दिया है और सूची सूची को बनाने के लिए मैंने सूची बनाने के लिए SortDescriptions को सूची संग्रह में जोड़ा है।संग्रह में आइटम पर बदलते अवलोकन संग्रह संपत्ति

मैं पर किसी भी बिंदु पर किसी भी संपत्ति को बदलते समय सूची का सहारा लेना चाहता हूं।

मेरे सभी बच्चे तत्व INotifyPropertyChanged लागू करते हैं।

+0

तो, आप अपने ओसी एक लिस्टबॉक्स के लिए बाध्य कर रहे हैं और लिस्टबॉक्स पर sortdescription है? – apandit

+0

यह सही है। जब एक बच्चे की वस्तु बदल जाती है, तो मैं इस बदलाव को प्रतिबिंबित करना चाहता हूं। – Nate

उत्तर

12

ब्रूट बल:

  1. अपने CollectionViewSource
  2. कॉल ताज़ा से प्रत्येक बच्चे आइटम
  3. ले लो ListCollectionView के लिए प्रत्येक PropertyChanged घटना के लिए हैंडलर देते हैं।

संपादित करें:

कोड 1 के लिए, 2 अपने में रहते हैं कोड-पीछे।

# 1 के लिए, आप की तरह कुछ करना चाहते हैं:

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 के लिए, अपने CollectionChanged हैंडलर में, आप की तरह कुछ करना होगा:

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

EDIT2: हालांकि, में इस मामले में, मैं दृढ़ता से सुझाव देता हूं कि आप ListCollectionView.NeedsRefresh भी जांचें और सेट होने पर ही ताज़ा करें। आपकी संपत्तियों में बदलाव होने पर पुन: क्रमबद्ध करने का कोई कारण नहीं है जो इस प्रकार को प्रभावित नहीं करता है।

+0

क्या यह कोड मेरे प्रस्तुति स्तर में लाइव होगा? Window.Xaml.Cs? # 1 और # 2 के लिए कोड क्या होगा? – Nate

+0

यही वही है जो मुझे चाहिए था। मैं केवल दूसरे भाग का उपयोग कर समाप्त हुआ, क्योंकि मेरे मामले में मेरे पास एक ऐसा ईवेंट है जो परिवर्तन कर रहा है, इसलिए मुझे केवल # 2 की आवश्यकता है। – Nate

0

यह काम करता है। जब भी संग्रह बदलता है, तो यह संग्रह को फिर से व्यवस्थित करता है। एक और अधिक कुशल तरीके से करने योग्य हो सकता है लेकिन यह इसका सारांश है।

 

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

अवलोकन योग्य चयन अपने तत्वों पर PropertyChanged घटनाओं को नहीं सुनता है, इसलिए तत्वों में से किसी एक की संपत्ति बदल जाने पर यह फिर से सॉर्ट करने में विफल हो जाएगी। http://msdn.microsoft.com/en-us/magazine/dd252944.aspx – Odrade

संबंधित मुद्दे