在 Silverlight AutoCompleteBox 中加载大量数据






4.78/5 (7投票s)
创建一个自定义的 AutoCompleteBox,它可以快速过滤大量数据。
目录
引言
AutoCompleteBox
是 Silverlight 中一个非常有用的控件。 它根据分配给它的 ItemsSource
的输入向用户提供建议。 当添加有限数量的项作为 ItemsSource
时,此控件运行良好; 比如几千个条目。 但如果分配给它的项目增加到 20000+ 以上,UI 将会挂起,这将造成不好的用户体验。
对于普通应用程序,可能不会期望出现如此庞大的数据,但在业务应用程序中,这是一种完全可能出现的情况。 在我之前的项目中,我遇到了这种情况。 我通过调整 AutoCompleteBox
的一个属性(TextFilter
)解决了这个问题,它给了我一个非常好的结果。 我想分享一下这个方法,以便对在 Silverlight 中有类似需求的人有所帮助。
先决条件
此示例应用程序是在 VS-2010 Express 版本和 Silverlight 4 中开发的。如果您尚未安装它们,请从 Microsoft 网站下载。 我使用 Silverlight 导航项目创建了示例应用程序。
修改 AutoCompleteBox 以加载海量数据
请参阅示例应用程序的屏幕截图
在这里,页面有一个来自 SDK 的 AutoCompleteBox
,它加载了 20,000 个字符串。
sourceList = new List<string>();
for (int i = 0; i < 20000; i++)
{
sourceList.Add("Item-" + i);
}
this.acbSample.ItemsSource = sourceList;
如果用户尝试输入一个字母,AutoCompleteBox
将不会加载数据,并且页面将挂起。 最终,数据会在一段时间后加载。 这种延迟会随着数据的增加而增加。 这是因为控件试图加载所有条目,然后尝试匹配数据。 如果我们可以限制在 AutoCompleteBox
下拉列表中加载的项的数量,我们可以提高加载性能。 设置 MaxDropDownHeight
属性在这里无济于事,因为这只会限制下拉列表的高度,并且控件仍然会尝试加载所有内容。 因此,我在用户控件中创建了一个自定义的 AutoCompleteBox
,其中包含一个 AutoCompleteBox
。 这存在于附加解决方案中的 FastLoadingACB 库中。
如您所见,在 FastLoadingACB.xaml.cs 中,只有必需的属性被公开为依赖属性 (DP)。 我在新用户控件中公开了 AutoCompleteBox
的 Width
和 ItemsSource
属性。 AutoCompleteBox
的 SelectionChangedEvent
也暴露在用户控件中。 在用户控件中添加了一个名为 MaxItemsInDropDown
的新 DP,以限制在 AutoCompleteBox
下拉列表中加载的项的数量。 限制项目数量的魔力是通过修改 AutoCompleteBox
的 AutoCompleteFilterPredicate<string> TextFilter
属性来实现的。 该属性的元数据文档为“获取或设置使用用户输入文本以文本方式过滤 System.Windows.Controls.AutoCompleteBox.ItemsSource
属性指定的项目的自定义方法,以便在下拉列表中显示”。 在 AutoCompleteBox
的 Loaded
事件中,为 TextFilter
提供了一个新的谓词,如下所示
private void acbFastLoading_Loaded(object sender, RoutedEventArgs e)
{
this.acbFastLoading.TextFilter = (search, value) =>
{
if (value.Length > 0)
{
if ((this.counter < MaxItemsInDropDown) &&
(value.ToUpper().StartsWith(search.ToUpper()) ||
value.ToUpper().Contains(search.ToUpper())))
{
this.counter++;
return true;
}
else
return false;
}
else
return false;
};
}
引入了一个私有成员计数器,当 AutoCompleteBox
的文本更改时,该计数器设置为 0,如上所示。 这将确保每当用户键入内容时,只有在 MaxItemsInDropDown
中提到的项目数量才会填充在下拉列表中。 现在,新控件加载了 200,000 个字符串; 比之前的情况多 10 倍。
IList<string> sourceList = new List<string>();
for (int i = 0; i < 200000; i++)
{
sourceList.Add("Item-" + i);
}
this.acbFastLoading.FastLoadingACBItemsSource = sourceList;
如您所见,数据被过滤并快速加载到下拉列表中。
结论
这种方法是一种提高 AutoCompleteBox
的加载和过滤性能的简单方法。 消耗应用程序所需的任何/所有属性都应作为依赖属性在新创建的用户控件中公开。 当应用程序加载少量数据时,可能不需要这种方法,但如果您使用大量数据,它将非常有用。 编码愉快…