我有主流(IEnumerable),超过100,000件商品。然后我控制了多个AutoCompleteBox
。所有这些AutoCompleteBox都绑定到主流。
首先
现在问题是我的控件中有大约10个AutoCompleteBox,并且所有主流都是他们的ItemsSource,从而导致大量内存占用。
第二
我还需要在运行时根据某些事件在少数AutoCompleteBox的ItemsSource上应用过滤器。
我需要你的建议来减少这种内存占用,并具有在运行时应用过滤器的功能。
答案 0 :(得分:0)
内存占用
我认为这不仅取决于您的代码实现,还取决于AutocompleteControlas,它如何使用绑定数据源。
在getter中将MainStream实现为带有yield return
的计算属性,以便在运行时按需计算/返回项目
对于WPF4,请查看是否使用WPF Data Virtualization进行AutocompleteControl。基本上,您可以重新定义标准项面板以使用VirtualizingStackPanel
而不是StackPanel
,因此框架将分配内存并仅为可见项创建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");
}
}
}
答案 1 :(得分:0)
对于数据收集的内存占用,您应该查找Sequential Data Cache
减少内存消耗的示例:
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; }
}