2012-05-13 17 views
11

मेरे पास एक WPF एप्लिकेशन है जो एमवीवीएम डेटा बाइंडिंग का उपयोग करता है। मैं ObservableCollection<...> में आइटम जोड़ रहा हूं और उनमें से बहुत से वास्तव में।क्या मैं किसी भी तरह अस्थायी रूप से WPF डेटा बाध्यकारी परिवर्तन अक्षम कर सकता हूं?

अब मैं सोच रहा हूं कि हर बार जब मैं संग्रह में एक जोड़ता हूं, तो क्या यह तुरंत घटना को आग लगा देता है और अनावश्यक ओवरहेड का कारण बनता है? यदि हां, तो क्या मैं किसी भी तरह से अस्थायी रूप से ईवेंट नोटिफिकेशन को अक्षम कर सकता हूं और मैन्युअल रूप से इसे मेरे कोड के अंत में एक बार फायर कर सकता हूं ताकि अगर मैं 10k आइटम जोड़ूं, तो इसे केवल 10k बार के बजाय निकाल दिया जाता है?

अद्यतन:

using System; 
using System.Linq; 
using System.Collections.Specialized; 
using System.Collections.Generic; 

namespace MyProject 
{ 

    /// <summary> 
    /// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed. 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    public class ObservableCollection<T> : System.Collections.ObjectModel.ObservableCollection<T> 
    { 

     /// <summary> 
     /// Adds the elements of the specified collection to the end of the ObservableCollection(Of T). 
     /// </summary> 
     public void AddRange(IEnumerable<T> collection) 
     { 
      foreach (var i in collection) Items.Add(i); 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, collection.ToList())); 
     } 

     /// <summary> 
     /// Removes the first occurence of each item in the specified collection from ObservableCollection(Of T). 
     /// </summary> 
     public void RemoveRange(IEnumerable<T> collection) 
     { 
      foreach (var i in collection) Items.Remove(i); 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, collection.ToList())); 
     } 

     /// <summary> 
     /// Clears the current collection and replaces it with the specified item. 
     /// </summary> 
     public void Replace(T item) 
     { 
      ReplaceRange(new T[] { item }); 
     } 
     /// <summary> 
     /// Clears the current collection and replaces it with the specified collection. 
     /// </summary> 
     public void ReplaceRange(IEnumerable<T> collection) 
     { 
      List<T> old = new List<T>(Items); 
      Items.Clear(); 
      foreach (var i in collection) Items.Add(i); 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, collection.ToList())); 
     } 

     /// <summary> 
     /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class. 
     /// </summary> 
     public ObservableCollection() : base() { } 

     /// <summary> 
     /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class that contains elements copied from the specified collection. 
     /// </summary> 
     /// <param name="collection">collection: The collection from which the elements are copied.</param> 
     /// <exception cref="System.ArgumentNullException">The collection parameter cannot be null.</exception> 
     public ObservableCollection(IEnumerable<T> collection) : base(collection) { } 
    } 
} 

मैं अब इस त्रुटि मिलती है:

अतिरिक्त जानकारी: रेंज कार्रवाई समर्थित नहीं हैं मैं इस वर्ग के होने की कोशिश की।

त्रुटि यहाँ आता है:

OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, collection.ToList())); 

उत्तर

10

एक बहुत ही त्वरित और आसान तरीका ObservableCollection उपवर्ग और सूचनाएं निलंबित करने के लिए है AddRange कहा जाता है। स्पष्टीकरण के लिए following blog post देखें।

8

वहाँ "मुश्किल" जिस तरह की तरह है, लेकिन बहुत सही, मेरी राय में, इस लक्ष्य को हासिल करने के लिए। आपको ObservableCollection लिखना है और AddRange हैंडलिंग लागू करना है।

इस तरह आप अपने सभी 10k तत्वों कुछ "धारक संग्रह" में और बाद, एक बार जब आप समाप्त होने पर, जोड़ सकते हैं की AddRange का उपयोग अपनेObservableColleciton कि क्या करना है।

इस पर अधिक आप इस लिंक पर पा सकते हैं:

ObservableCollection Doesn't support AddRange method....

या यह एक बहुत

AddRange and ObservableCollection

+1

दिलचस्प। मुझे आश्चर्य है कि यह 'ObservableCollection' का हिस्सा क्यों नहीं है। – Tower

+0

@rFactor: honeslty, कोई जानकारी नहीं है। इसे अंतर्निहित बनाना बहुत अच्छा होगा, लेकिन ... हो सकता है, एरिक लिपर्ट कभी-कभी कहता है: क्योंकि इसे लागू नहीं किया गया ... – Tigran

+0

मैं उन्हें काम करने में असमर्थ हूं, मुझे मिलता है: 'अतिरिक्त जानकारी : कन्स्ट्रक्टर केवल 'रीसेट' कार्रवाई का समर्थन करता है।'जब कोड' ऑनकॉलेक्शन चेंज किया जाता है (नया अधिसूचना कोलेक्शन चेंजएडएन्टएआरजीएस (नोटिफ़ाई कोलेक्शन चेंजएड एक्शन। जोड़ें); '। – Tower

6

पर्यवेक्षण चयन का यह विस्तार आसानी से समस्या हल करता है।

यह एक सार्वजनिक SupressNotification प्रॉपर्टी का खुलासा करता है ताकि उपयोगकर्ता को नियंत्रित करने की अनुमति मिल सके जब संग्रहChanged अधिसूचना दबा दी जाएगी।

यह रेंज सम्मिलन/हटाने की पेशकश नहीं करता है, लेकिन यदि संग्रह परिवर्तनित अधिसूचना दबा दी जाती है, तो संग्रह पर सीमा संचालन करने की आवश्यकता अधिकांश मामलों में कम हो जाती है।

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

public class ObservableCollectionEx<T> : ObservableCollection<T> 
{ 
    private bool _notificationSupressed = false; 
    private bool _supressNotification = false; 
    public bool SupressNotification 
    { 
     get 
     { 
      return _supressNotification; 
     } 
     set 
     { 
      _supressNotification = value; 
      if (_supressNotification == false && _notificationSupressed) 
      { 
       this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 
       _notificationSupressed = false; 
      } 
     } 
    } 

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) 
    { 
     if (SupressNotification) 
     { 
      _notificationSupressed = true; 
      return; 
     } 
     base.OnCollectionChanged(e); 
    } 
} 
+0

नाइस क्लास, मुझे सॉल्चरेशन पसंद है कि आप इसे फिर से सेट करने के बाद ईवेंट को आग लगाना चाहते हैं। – Tobias

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

  • कोई संबंधित समस्या नहीं^_^