2015-02-10 3 views
5

मेरे पास दो ICollectionView एस के साथ व्यूमोडेल है जो ItemsSource से दो अलग ListBox es के रूप में बाध्य हैं। दोनों एक ही ObservableCollection लपेटें, लेकिन विभिन्न फ़िल्टर के साथ। सब कुछ शुरुआत में ठीक काम करता है और दोनों सूची बॉक्स ठीक से भरते दिखाई देते हैं।ICollectionView का SourceCollection शून्य है

हालांकि जब मैं ऑब्जर्जेबल कोलेक्शन में कोई आइटम बदलता हूं और फ़िल्टरिंग के लिए प्रासंगिक संपत्ति को संशोधित करता हूं, तो सूची बॉक्स अपडेट नहीं होते हैं। डीबगर में मैंने पाया कि ICollectionVIews दोनों के लिए SourceCollection शून्य है हालांकि मेरा ObservableCollection अभी भी वहां है।

यह कैसे मुझे यकीन है कि ICollectionViews को दूर करने और एक ही आइटम जोड़कर अपडेट किया जाता है बनाने के लिए एक आइटम संशोधित है:

private void UnassignTag(TagViewModel tag) 
{ 
    TrackChangedTagOnCollectionViews(tag, t => t.IsAssigned = false); 
} 

private void TrackChangedTagOnCollectionViews(TagViewModel tag, Action<TagViewModel> changeTagAction) 
{ 
    _tags.Remove(tag); 

    changeTagAction.Invoke(tag); 

    _tags.Add(tag); 
} 

तंत्र एक और संदर्भ में, जहां मैं एक ही कक्षा का उपयोग में काम करता है।

मुझे यह भी एहसास हुआ कि अगर मैं आईसीओलेक्शन व्यूज़ कलेक्शन चेंजेड इवेंट्स पर श्रोताओं को पंजीकृत करता हूं तो समस्या गायब हो जाती है। मैंने यह सुनिश्चित किया है कि मैं उन्हें जीयूआई थ्रेड से बना और संशोधित करता हूं और संदेह करता हूं कि कचरा संग्रह समस्या है, लेकिन वर्तमान में मैं अटक गया हूं ... विचार?

अद्यतन:

डिबगिंग जबकि मैंने महसूस किया कि SourceCollections अभी भी वहाँ सही इससे पहले कि मैं WinForms प्रपत्र जिसमें मेरी UserControl होस्ट किया गया है पर ShowDialog() कहते हैं। जब संवाद दिखाया जाता है तो वे चले गए हैं।

मैं इस तरह ICollectionViews बनाएँ:

AvailableTags = new CollectionViewSource { Source = _tags }.View; 
AssignedTags = new CollectionViewSource { Source = _tags }.View; 

यहां बताया गया है मैं दो (एक दूसरे को बहुत समान है) में से एक के लिए बाध्य:

<ListBox Grid.Column="0" ItemsSource="{Binding AvailableTags}" Style="{StaticResource ListBoxStyle}"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <Border Style="{StaticResource ListBoxItemBorderStyle}"> 
         <DockPanel> 
          <Button DockPanel.Dock="Right" ToolTip="Assign" Style="{StaticResource IconButtonStyle}" 
              Command="{Binding Path=DataContext.AssignSelectedTagCommand, RelativeSource={RelativeSource AncestorType={x:Type tags:TagsListView}}}" 
              CommandParameter="{Binding}"> 
           <Image Source="..."/> 
          </Button> 

          <TextBlock Text="{Binding Name}" Style="{StaticResource TagNameTextBlockStyle}"/> 
         </DockPanel> 
        </Border> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 

मैं में MvvmLight के RelayCommand<T>ICommand के रूप में कार्यान्वयन का उपयोग मेरा व्यू मॉडेल:

AssignSelectedTagCommand = new RelayCommand<TagViewModel>(AssignTag); 
+1

कृपया अधिक कोड पोस्ट करें। –

+0

@ सिनाटर: मुझे संदेह है कि इसके साथ इसका कोई संबंध नहीं है। INotifyProperty वस्तुओं पर छेड़छाड़ फ़िल्टरिंग के लिए कोई फर्क नहीं पड़ता है (और जैसा कि मैंने लिखा है: यह एक अलग संदर्भ में काम करता है)। मुझे निकालने/जोड़ने का विचार मिला [यहां] (http://drwpf.com/blog/2008/10/20/itemscontrol-e-is-for-editable-collection/)। – EagleBeak

+0

@ गणेश: क्या आप अधिक विशिष्ट हो सकते हैं? मुझे इस बात का नुकसान हुआ है कि पोस्ट को छेड़छाड़ किए बिना कौन सा कोड पोस्ट करना है। ObservableCollection कहीं और संशोधित नहीं है। आईसीओलेक्शन व्यू भी नहीं हैं। – EagleBeak

उत्तर

9

मेरे पास यह था एक समान उपयोग-मामले के साथ भी जारी करें। जब मैंने अंतर्निहित संग्रह को अपडेट किया, तो मैं सभी फ़िल्टर किए गए दृश्यों पर Refresh() पर कॉल करूंगा। कभी-कभी, इसके परिणामस्वरूप NullReferenceExceptionListCollectionView.PrepareLocalArray() के भीतर से फेंक दिया जाएगा क्योंकि SourceCollection शून्य है।

समस्या यह है कि आपको CollectionView पर बाध्यकारी नहीं होना चाहिए, लेकिन CollectionViewSource.View संपत्ति पर बाध्यकारी नहीं होना चाहिए।

यहाँ कैसे मैं यह कर दिया गया है:

public class ViewModel { 

    // ... 

    public ViewModel(ObservableCollection<ItemViewModel> items) 
    { 
     _source = new CollectionViewSource() 
     { 
      Source = items, 
      IsLiveFilteringRequested = true, 
      LiveFilteringProperties = { "FilterProperty" } 
     }; 

     _source.Filter += (src, args) => 
     { 
      args.Accepted = ((ItemViewModel) args.Item).FilterProperty == FilterField; 
     }; 
    } 

    // ... 

    public ICollectionView View 
    { 
     get { return _source.View; } 
    } 

    // ... 
} 
+0

वाह? वह बिल्कुल वही कर रहा है: नया संग्रह दृश्य स्रोत {स्रोत = _tags}। देखें; –

+2

यह बिल्कुल वही नहीं है। 'CollectionViewSource.View' एक संपत्ति है, और मान बदलता है। – sconzey

+0

क्या? मैंने आपके रास्ते की कोशिश की और यह काम करता है, लेकिन मैं पूरी तरह से समझ में नहीं आता क्यों ... डाउनवोट के लिए खेद है, यह स्वीकार्य उत्तर होना चाहिए! –

0

अपनी समस्या के लिए कारण यह है कि CollectionViewSource हो रही कचरा एकत्र किया जाता है है।

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