我正在尝试在您键入功能时实现搜索功能(如默认电子邮件应用中的搜索功能) - 我有一个包含50个项目的列表框 - 每个项目都绑定到具有字符串字段的类对象。 。我希望搜索和显示在其字符串字段中的搜索框中包含文本的项目 - 这是用户键入文本框...尝试了几种方法 - >
1>>使用CollectionViewSource
- 将CollectionViewSource绑定到DB中的所有项目
- 将列表框绑定到CollectionViewSource
- 设置CollectionViewSource的过滤器属性 - 其功能在项目的搜索框中搜索文本,并在每个键盘事件上设置e.Accepted -
- 过滤工作正常但速度慢50项:( - 猜测过滤每个项目的过滤器并检查是否将e.Accepted属性设置为true
....一个DB调用加载,但似乎是很多处理来决定由CollectionViewSource在文件管理器中显示哪个元素
2>>过滤@ DB级别
- 在keyup上 - 将搜索框中的文本发送到ViewModel,其中函数返回一个ObservableCollection对象,该对象具有搜索字符串
- ObservableCollection绑定到列表框
....顶层没有多少处理,但每个Keypress上有多个DB调用 - 仍然很慢,但比Approach One快一点
你会推荐其他approch吗?或进一步优化上述方法的任何建议? - 任何调整,以使搜索顺利运作?
第一次进入移动设备开发:) ... Thanx提前:)
答案 0 :(得分:1)
您可以通过将搜索操作延迟x毫秒来进一步优化搜索过程,以允许用户继续编写搜索条件。这样,每个新类型的char都会将搜索操作延迟xxx毫秒,直到触发操作的最后一个char,只需一次调用就可以获得更好的性能,而不是说10次调用。从技术上讲,您可以通过使用Timer类来实现此目的。 在这里,您将找到一个示例源代码示例,向您展示如何实现它。
private void txtSearchCriteria_TextChanged(object sender, TextChangedEventArgs e)
{
if (txtSearchCriteria.Text == "Search ...")
return;
if (this.deferredAction == null)
{
this.deferredAction = DeferredAction.Create(() => ApplySearchCriteria());
}
// Defer applying search criteria until time has elapsed.
this.deferredAction.Defer(TimeSpan.FromMilliseconds(250));
}
private DeferredAction deferredAction;
private class DeferredAction
{
public static DeferredAction Create(Action action)
{
if (action == null)
{
throw new ArgumentNullException("action");
}
return new DeferredAction(action);
}
private Timer timer;
private DeferredAction(Action action)
{
this.timer = new Timer(new TimerCallback(delegate
{
Deployment.Current.Dispatcher.BeginInvoke(action);
}));
}
public void Defer(TimeSpan delay)
{
// Fire action when time elapses (with no subsequent calls).
this.timer.Change(delay, TimeSpan.FromMilliseconds(-1));
}
}
public void ApplySearchCriteria()
{
ICollectionView dataView = this.ViewSource.View;
string criteria = this.txtSearchCriteria.Text;
string lowerCriteria = criteria.ToLower();
using (dataView.DeferRefresh())
{
Func<object, bool> filter = word =>
{
bool result = word.ToString().ToLower().StartsWith(lowerCriteria);
return result;
};
dataView.Filter = l => { return filter.Invoke(l); };
}
this.lstWords.ItemsSource = dataView;
if (this.lstWords.Items.Count != 0)
{
this.lblError.Visibility = Visibility.Collapsed;
}
else
{
this.lblError.Visibility = Visibility.Visible;
}
}