0

我有一些小应用程序可以读取一个非常大的文件。为了显示这个文件(可以有大约百万行),我使用 virtualizedStackpanel 和滚动视图来虚拟化 UI。

在这个文件中,我实现了类似搜索的功能,它突出显示包含搜索字符串的行。每行由文本块表示。

所以我有我的集合绑定到的 ItemsControl。作为项目数据模板,我有 contentControl(带有高亮转换器,因此行会改变颜色)并且 ItemsPanelTemplate 是 VirtualizingStackPanel 和 ItemsControl 的 ControlTemplate 是带有嵌套 ItemsPresenter 的 ScrollViewer

    <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)中,我有一个接受字符串的函数,并在包含所有行的 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 这样的东西,这甚至可能吗?

4

1 回答 1

1

看来您正在尝试在这里重新发明轮子,为什么不使用一些可用的控件,例如

https://github.com/keyoti/RapidFindReplaceWPF

https://www.codeproject.com/Articles/173509/A-Universal-WPF-Find-Replace-Dialog

于 2018-05-26T10:09:31.243 回答