2012-02-23 120 views
1

我有一個主流(IEnumerable)超過100,000個項目。然後在我的控制下有多個AutoCompleteBox。所有這些AutoCompleteBox綁定到主流。減少內存佔用

第一:

現在的問題是我有大約10 AutoCompleteBox在我的控制,並全部具有主流作爲自己的ItemsSource從而導致較大的內存佔用。

二:

我還需要有能夠在運行時根據一些事件的幾個AutoCompleteBox的的ItemsSource應用過濾器的功能。

我需要你的建議來減少這種內存佔用,並具有在運行時應用過濾器的功能。

+0

1)? 2)MainStream是一個getter的proeprty,它返回一個請求/惰性getter的項目列表,或者這是一次填充的字段/屬性? – sll 2012-02-23 13:31:40

回答

0

內存佔用

我相信這不僅是從你的代碼實現,但是從AutocompleteControlas取決於好,它如何使用綁定的數據源。在運行時

    • 實現主流作爲吸氣使項目將與計算計算yield return財產/返回點播對於WPF4看到AutocompleteControl是否使用WPF數據虛擬化。基本上,您可以重新定義標準項目面板以使用VirtualizingStackPanel而不是StackPanel,因此框架將分配內存並僅爲可見項創建UI元素,而不是爲所有邊界創建UI元素。

    在即時過濾

    看看在MVVM的做法。這將很容易使用綁定到UI過濾器控制的屬性來計算MainSTream項目,基本上getter會使用公共綁定的屬性,每當這些屬性發生變化時 - MainSTream會重新計算項目並通過INotifyPropertyChanged通知UI,顯然你需要實現對INotifyPropertyChanged。見One sentence explanation to MVVM in WPF?

    public IEnumerable<IMyItem> MainStream 
    { 
        get 
        { 
         foreach(var item in mainDataSource) 
         { 
         if (item.Name == this.NameFilterBoundToUiTextBox) 
         { 
          yield return item; 
         } 
         } 
        } 
    } 
    
    private string nameFilter; 
    public string NameFilterBoundToUiTextBox 
    { 
        get 
        { 
         return this.nameFilter; 
        } 
        set 
        { 
         if (this.nameFilter != value) 
         { 
         this.nameFilter = value; 
    
         // TODO: Implement INotifyPropertyChanged 
         this.OnPropertyChanged("NameFilterBoundToUiTextBox"); 
    
         // THis would notify UI to rebind MainSream 
         this.OnPropertyChanged("MainStream"); 
         } 
        } 
    } 
    
  • 0

    對於數據收集的內存佔用你應該找Sequential Data Cache

    樣品,以減少內存消耗:您使用的MVVM

    public void TestAutoCompleteLookup() 
        { 
         var path = ""; 
         using (var c = SequentialDataCache<AutoCompleteItem>.Initialize()) 
         { 
          path = c.Path; 
    
          //add 100.000 items 
          for (int i = 0; i < 100000; i++) 
          { 
           c.Add(new AutoCompleteItem() { Text = string.Format("{0}Text", i) }); 
          } 
    
          //query 
          var pattern = "1"; 
          var items = c.Where(autoCompleteItem => autoCompleteItem.Text.StartsWith(pattern)).ToArray(); 
    
         } 
    
         if (File.Exists(path)) 
          File.Delete(path); 
        } 
    
        [Serializable] 
        private class AutoCompleteItem 
        { 
         public string Text { get; set; } 
        }