private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e) { TextChange textChange = e.Changes.Last(); // We will invoke completion on text insertion and not deletion. // Also, we don't want to invoke completion on dialog load as we pre populate the target // location textbox with name of the folder when dialog is initially loaded. if (textChange.AddedLength > 0 && SearchTextBox.CaretIndex > 0) { ThreadHelper.JoinableTaskFactory.RunAsync(async() => { // grab these WPF dependant things while we're still on the UI thread int caretIndex = SearchTextBox.CaretIndex; SearchTextBoxViewModel viewModel = ViewModel; string textBeforeGetCompletion = SearchTextBox.Text; // Switch to a background thread to not block the UI thread, as this operation can take // a while for slow network connections await TaskScheduler.Default; CompletionSet completionSet = await viewModel.GetCompletionSetAsync(caretIndex); await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); // If the value has changed then this request is out of date. // If focus is elsewhere the work below won't be used anyway if (textBeforeGetCompletion != SearchTextBox.Text || !SearchTextBox.IsFocused) { return; } if (completionSet.Completions == null || !completionSet.Completions.Any()) { Flyout.IsOpen = false; return; } // repopulate the completion list CompletionEntries.Clear(); foreach (CompletionItem entry in completionSet.Completions) { CompletionEntries.Add(new CompletionEntry(entry, completionSet.Start, completionSet.Length)); } PositionCompletionPopup(completionSet.Length); if (CompletionEntries != null && CompletionEntries.Count > 0 && Options.SelectedIndex == -1) { CompletionItem selectionCandidate = await ViewModel.GetRecommendedSelectedCompletionAsync( completionSet: completionSet, lastSelected: SelectedItem?.CompletionItem); SelectedItem = CompletionEntries.FirstOrDefault(x => x.CompletionItem.InsertionText == selectionCandidate.InsertionText) ?? CompletionEntries[0]; Options.ScrollIntoView(SelectedItem); } Flyout.IsOpen = true; }); } }
private void LibrarySearchBox_TextChanged(object sender, TextChangedEventArgs e) { OnPropertyChanged(nameof(IsTextEntryEmpty)); TextChange textChange = e.Changes.Last(); // We will invoke completion on text insertion and not deletion. if (textChange.AddedLength > 0 && !string.IsNullOrEmpty(Text)) { VisualStudio.Shell.ThreadHelper.JoinableTaskFactory.Run(async() => { CompletionSet completionSet = await SearchService?.Invoke(Text, LibrarySearchBox.CaretIndex); if (completionSet.Equals(null) || !completionSet.Completions.Any()) { Flyout.IsOpen = false; return; } int atIndex = Text.IndexOf('@'); if (atIndex >= 0) { completionSet.Completions = FilterOutUnmatchedItems(completionSet.Completions, Text.Substring(atIndex + 1)); } CompletionEntries.Clear(); foreach (CompletionItem entry in completionSet.Completions) { CompletionEntries.Add(new CompletionEntry(entry, completionSet.Start, completionSet.Length)); } PositionCompletions(completionSet.Length); if (CompletionEntries != null && CompletionEntries.Count > 0 && Options.SelectedIndex == -1) { if (atIndex >= 0) { SelectedItem = CompletionEntries.FirstOrDefault(x => x.CompletionItem.DisplayText.StartsWith(Text.Substring(atIndex + 1), StringComparison.OrdinalIgnoreCase)) ?? CompletionEntries[0]; } else { string lastSelected = SelectedItem?.CompletionItem.InsertionText; SelectedItem = CompletionEntries.FirstOrDefault(x => x.CompletionItem.InsertionText == lastSelected) ?? CompletionEntries[0]; } Options.ScrollIntoView(SelectedItem); Flyout.IsOpen = true; } }); } }
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e) { TextChange textChange = e.Changes.Last(); // We will invoke completion on text insertion and not deletion. // Also, we don't want to invoke completion on dialog load as we pre populate the target // location textbox with name of the folder when dialog is initially loaded. if (textChange.AddedLength > 0 && SearchTextBox.CaretIndex > 0) { VisualStudio.Shell.ThreadHelper.JoinableTaskFactory.Run(async() => { CompletionSet completionSet = await ViewModel.GetCompletionSetAsync(SearchTextBox.CaretIndex); if (completionSet.Completions == null || !completionSet.Completions.Any()) { Flyout.IsOpen = false; return; } // repopulate the completion list CompletionEntries.Clear(); foreach (CompletionItem entry in completionSet.Completions) { CompletionEntries.Add(new CompletionEntry(entry, completionSet.Start, completionSet.Length)); } PositionCompletionPopup(completionSet.Length); if (CompletionEntries != null && CompletionEntries.Count > 0 && Options.SelectedIndex == -1) { CompletionItem selectionCandidate = await ViewModel.GetRecommendedSelectedCompletionAsync( completionSet: completionSet, lastSelected: SelectedItem?.CompletionItem); SelectedItem = CompletionEntries.FirstOrDefault(x => x.CompletionItem.InsertionText == selectionCandidate.InsertionText) ?? CompletionEntries[0]; Options.ScrollIntoView(SelectedItem); } Flyout.IsOpen = true; }); } }
private void TargetLocationSearchTextBox_TextChanged(object sender, TextChangedEventArgs e) { TextChange textChange = e.Changes.Last(); // We will invoke completion on text insertion and not deletion. // Also, we don't want to invoke completion on dialog load as we pre populate the target // location textbox with name of the folder when dialog is initially loaded. if (textChange.AddedLength > 0 && TargetLocationSearchTextBox.CaretIndex > 0) { VisualStudio.Shell.ThreadHelper.JoinableTaskFactory.Run(async() => { CompletionSet completionSet = await SearchService?.Invoke(Text, TargetLocationSearchTextBox.CaretIndex); if (completionSet.Equals(null) || !completionSet.Completions.Any()) { Flyout.IsOpen = false; return; } CompletionEntries.Clear(); foreach (CompletionItem entry in completionSet.Completions) { CompletionEntries.Add(new CompletionEntry(entry, completionSet.Start, completionSet.Length)); } PositionCompletions(completionSet.Length); if (CompletionEntries != null && CompletionEntries.Count > 0 && Options.SelectedIndex == -1) { string lastSelected = SelectedItem?.CompletionItem.InsertionText; SelectedItem = CompletionEntries.FirstOrDefault(x => x.CompletionItem.InsertionText == lastSelected) ?? CompletionEntries[0]; Options.ScrollIntoView(SelectedItem); } Flyout.IsOpen = true; }); } InstallationFolder.DestinationFolder = TargetLocationSearchTextBox.Text; }