65.9K
CodeProject 正在变化。 阅读更多。
Home

在 Silverlight AutoCompleteBox 中加载大量数据

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.78/5 (7投票s)

2011年7月28日

CPOL

3分钟阅读

viewsIcon

59400

downloadIcon

1559

创建一个自定义的 AutoCompleteBox,它可以快速过滤大量数据。

目录

  1. 引言
  2. 必备组件
  3. 修改 AutoCompleteBox 以加载海量数据
  4. 结论

引言

AutoCompleteBox 是 Silverlight 中一个非常有用的控件。 它根据分配给它的 ItemsSource 的输入向用户提供建议。 当添加有限数量的项作为 ItemsSource 时,此控件运行良好; 比如几千个条目。 但如果分配给它的项目增加到 20000+ 以上,UI 将会挂起,这将造成不好的用户体验。

对于普通应用程序,可能不会期望出现如此庞大的数据,但在业务应用程序中,这是一种完全可能出现的情况。 在我之前的项目中,我遇到了这种情况。 我通过调整 AutoCompleteBox 的一个属性(TextFilter)解决了这个问题,它给了我一个非常好的结果。 我想分享一下这个方法,以便对在 Silverlight 中有类似需求的人有所帮助。

先决条件

此示例应用程序是在 VS-2010 Express 版本和 Silverlight 4 中开发的。如果您尚未安装它们,请从 Microsoft 网站下载。 我使用 Silverlight 导航项目创建了示例应用程序。

修改 AutoCompleteBox 以加载海量数据

请参阅示例应用程序的屏幕截图

Sample.jpg

在这里,页面有一个来自 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)。 我在新用户控件中公开了 AutoCompleteBoxWidthItemsSource 属性。 AutoCompleteBoxSelectionChangedEvent 也暴露在用户控件中。 在用户控件中添加了一个名为 MaxItemsInDropDown 的新 DP,以限制在 AutoCompleteBox 下拉列表中加载的项的数量。 限制项目数量的魔力是通过修改 AutoCompleteBoxAutoCompleteFilterPredicate<string> TextFilter 属性来实现的。 该属性的元数据文档为“获取或设置使用用户输入文本以文本方式过滤 System.Windows.Controls.AutoCompleteBox.ItemsSource 属性指定的项目的自定义方法,以便在下拉列表中显示”。 在 AutoCompleteBoxLoaded 事件中,为 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;

如您所见,数据被过滤并快速加载到下拉列表中。

Modified_ACB_DataLoad.jpg

结论

这种方法是一种提高 AutoCompleteBox 的加载和过滤性能的简单方法。 消耗应用程序所需的任何/所有属性都应作为依赖属性在新创建的用户控件中公开。 当应用程序加载少量数据时,可能不需要这种方法,但如果您使用大量数据,它将非常有用。 编码愉快…

© . All rights reserved.