Я работаю над созданием решения WPF, которое использует шаблон MVVM для асинхронной загрузки искомых элементов в элемент управления поиска. Элемент управления поиском, который является пользовательским элементом управления WPF, создается с помощью текстового поля для ввода текста поиска и кнопки поиска, а также скрытого списка, который будет виден при загрузке в него списка найденных элементов. Этот пользовательский элемент управления в свою очередь встроен в другое представление WPF, которое имеет древовидное представление определенных элементов. Это представление имеет модель представления, в которой логика загрузки искомых элементов представления дерева будет загружена в элемент управления поиском. Все это происходило синхронно, без использования какого-либо вызова диспетчера. Но после запроса на изменение я бы хотел, чтобы это происходило асинхронно в другом потоке с помощью Dispatcher.
Может ли кто-нибудь сообщить мне, как получить дескриптор Dispatcher элемента управления Search в классе модели представления, чтобы вызвать для него BeginInvoke с использованием шаблона MVVM, в котором моя модель View не знает о представлении? Любая подсказка будет высоко ценится.
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 я привязываю свойство Items элемента управления Search к 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>
Спасибо,
Sowmya