У меня есть небольшое приложение, которое читает очень большой файл.Чтобы отобразить этот файл (может иметь около миллионов строк), я использую virtualizedStackpanel и scrollview для виртуализации пользовательского интерфейса.
В этом файле я реализовал что-то вроде поиска, который выделяет строки, содержащие искомую строку.Каждая строка представлена текстовым блоком.
Итак, у меня есть ItemsControl, к которому я привязываю свою коллекцию.В качестве таблицы данных элемента у меня есть contentControl (с преобразователем выделения, поэтому строка будет менять цвет), а ItemsPanelTemplate - это VirtualizingStackPanel, а ControlTemplate ItemsControl - это ScrollViewer с вложенным ItemsPresenter
<ItemsControl Grid.Row="2" ItemsSource="{Binding FileContent}"
ScrollViewer.CanContentScroll="True"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding Text, Converter={StaticResource HighlightConverter}}">
</ContentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer >
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
В фоновом коде (ViewModel) у меня есть функция, которая принимаетstring и ищите эту строку в ObservableCollection, которая содержит все строки (и текстовые блоки сделаны из каждой строки).И два способа поиска.Первый метод находит результаты в коллекции и вставляет специальные символы в текст TextBlock, чтобы можно было использовать подсветку.(и вторая функция, которая удаляет выделенный текст из предыдущего поиска)
private void SearchText()
{
this.RemovePreviousSearchResults();
searchResults = new ObservableCollection<RowModel>(this.FileContent.Where(x => x.Text.Contains(this.TextToFind)));
foreach (RowModel row in searchResults)
{
row.UpdateTextWithNotify("|~S~|" + row.Text + "|~E~|");
}
}
private void RemovePreviousSearchResults()
{
if (this.searchResults.Count > 0)
{
foreach (RowModel row in searchResults)
{
row.UpdateTextWithNotify(row.Text.Replace("|~S~|", "").Replace("|~E~|", ""));
}
}
}
И теперь я хочу иметь некоторую возможность сфокусировать представление прокрутки на найденных результатах.Нечто подобное происходит, когда вы нажимаете CTRL + F в текстовом редакторе, а затем нажимаете «Найти далее».
Но я понятия не имею, как реализовать это, не нарушая правил MVVM.Я думал о добавлении еще какой-нибудь управляющей строки / символа в текстовый блок с результатами, но как я могу заставить прокрутку прокручивать прокрутку на них?
Возможно ли это вообще без ListView?