【发布时间】:2014-12-09 21:14:14
【问题描述】:
我正在创建一个 WPF 解决方案,它使用 MVVM 模式异步加载搜索控件中的搜索项。作为 WPF 用户控件的搜索控件是用一个文本框创建的,用于输入搜索文本和搜索按钮,以及一个隐藏的列表框,当它在其中加载搜索项目列表时,该列表框将可见。此用户控件依次嵌入到另一个 WPF 视图中,该视图具有某些项目的树视图。此视图有一个视图模型,其中加载树视图的搜索项的逻辑将加载到搜索控件中。一直以来,这一直在同步发生,无需使用任何 Dispatcher 调用。但是,在更改请求之后,我想使用 Dispatcher 在不同的线程中异步发生这种情况。
谁能告诉我如何在视图模型类中处理搜索控件的调度程序,以便使用我的视图模型不知道视图的 MVVM 模式对其调用 BeginInvoke?任何线索将不胜感激。
public ObservableCollection<Details> CatalogSearchResults { get; private set; }
private void ExecuteSearchCommand(object parameter)
{
CatalogSearchResults.Clear();
if (string.IsNullOrEmpty(parameter.ToString())) return;
searchtext = (string)parameter;
searchtext.Trim();
SetSearchResults();
}
private void SetSearchResults()
{
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += LoadResults;
bw.RunWorkerCompleted += this.LoadResultsCompleted;
bw.RunWorkerAsync();
}
private void LoadResults(object sender, DoWorkEventArgs args)
{
IsSearchInProgress = true;
foreach (var category in _rootCategory.Recurse(FindChildren))
{
if (category.CommentDetails != null)
{
//limitation - there is no direct way to add range to observable collection.
//Using linq query would result in two loops rather than one.
foreach (var node in category.Details)
{
if (node.Name.IndexOf(searchtext, StringComparison.CurrentCultureIgnoreCase) >= 0
|| node.PrecannedText.IndexOf(searchtext, StringComparison.CurrentCultureIgnoreCase) >= 0)
{
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
(ThreadStart)delegate { CatalogSearchResults.Add(node); });
Thread.Sleep(100);
}
}
}
}
IsSearchInProgress = false;
}
在 xaml 中,我将 Search 控件的 Items 属性绑定到 CatalogSearchResults:
<ctrl:SearchControl x:Name="Ctrl" Grid.RowSpan="2" HorizontalAlignment="Stretch" VerticalAlignment="Top" ToolTip="Search" Command="{Binding SearchCommand}" Grid.ColumnSpan="3"
CommandParameter="{Binding Text, RelativeSource={RelativeSource Self}}"
Items ="{Binding CatalogSearchResults}" > </ctrl:SearchControl>
谢谢, 苏米亚
【问题讨论】:
标签: wpf mvvm dispatcher