C#wpf使用scrollview搜索文本并在虚拟化stackpanel中查找下一个功能

时间:2018-05-26 09:35:02

标签: c# wpf mvvm ui-virtualization

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

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

所以我有ItemsControl我绑定我的集合。作为项目datatemplate我有contentControl(使用高亮转换器,因此行将更改颜色)和ItemsPanelTemplate是VirtualizingStackPanel和ItemsControl的ControlTemplate是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)中,我有一个接受字符串并在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~|", ""));
                }
            }
        }

现在我有能力将scrollview集中到找到的结果。在文本编辑器中按CTRL + F,然后单击“查找下一个”。

但我不知道如何在不违反MVVM规则的情况下实现这一点。我想在文本块中添加更多控制字符串/字符和结果,但是我如何强制滚动视图滚动到它们上?

如果没有像ListView这样的东西,这是否可行?

1 个答案:

答案 0 :(得分:1)

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

https://github.com/keyoti/RapidFindReplaceWPF

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