Преглед на файлове

BOTA - 添加搜索内容

chenrongqian преди 2 години
родител
ревизия
1a402e9c3a

+ 1 - 0
PDF Office/App.xaml.cs

@@ -129,6 +129,7 @@ namespace PDF_Office
             containerRegistry.RegisterForNavigation<ToolsBarContent>();
             containerRegistry.RegisterForNavigation<AnnotToolContent>();
             containerRegistry.RegisterForNavigation<BookmarkContent>();
+            containerRegistry.RegisterForNavigation<SearchContent>();
             containerRegistry.RegisterForNavigation<OutLineControl>();
             containerRegistry.RegisterForNavigation<ViewModularContent>();
             containerRegistry.RegisterForNavigation<SplitScreenContent>();

+ 98 - 0
PDF Office/DataConvert/WidthConvert.cs

@@ -0,0 +1,98 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+
+namespace PDF_Office.DataConvert
+{
+    public class WidthConvert : IValueConverter
+    {
+        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (value == null)
+            {
+                return 0;
+            }
+            else
+            {
+                if (value is double)
+                {
+                    double width = (double)value;
+                    width = width - SystemParameters.VerticalScrollBarWidth-8;
+                    return Math.Max(0, width);
+                }
+                else
+                {
+                    return 0;
+                }
+            }
+        }
+
+        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            throw new NotImplementedException();
+        }
+    }
+    public class SearchWidthConvert : IValueConverter
+    {
+        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (value == null)
+            {
+                return 0;
+            }
+            else
+            {
+                if (value is double)
+                {
+                    double width = (double)value;
+                    width = width - SystemParameters.VerticalScrollBarWidth-20;
+                    return Math.Max(0, width);
+                }
+                else
+                {
+                    return 0;
+                }
+            }
+        }
+
+        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            throw new NotImplementedException();
+        }
+    }
+    public class WidthMultiConvert : IMultiValueConverter
+    {
+        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (values == null || values.Length==0)
+            {
+                return 0;
+            }
+            else
+            {
+                if (values[0] is double)
+                {
+                    double width = (double)values[0];
+                    width = width - SystemParameters.VerticalScrollBarWidth - 8;
+                    return Math.Max(0, width);
+                }
+                else
+                {
+                    return 0;
+                }
+            }
+        }
+
+        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 228 - 0
PDF Office/Helper/RichTextBoxHelper.cs

@@ -0,0 +1,228 @@
+using ComPDFKit.PDFDocument;
+using PDF_Office.Model.BOTA;
+using PDF_Office.Views.BOTA;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Media;
+using System.Windows.Media.TextFormatting;
+
+namespace PDF_Office.Helper
+{
+    public class OutlineSerach { 
+          public string Title { get; set; }
+    }
+    public class RichTextBoxHelper : DependencyObject
+    {
+        public static FlowDocument GetDocumentBind(DependencyObject obj)
+        {
+            return (FlowDocument)obj.GetValue(DocumentBindProperty);
+        }
+        public static void SetDocumentBind(DependencyObject obj, FlowDocument value)
+        {
+            obj.SetValue(DocumentBindProperty, value);
+        }
+        public static FlowDocument GetOutlineSearchDocumentBind(DependencyObject obj)
+        {
+            return (FlowDocument)obj.GetValue(OutlineSearchDocumentBindProperty);
+        }
+        public static string searchWord = "";
+        public static void SetOutlineSearchDocumentBind(DependencyObject obj, FlowDocument value)
+        {
+            obj.SetValue(OutlineSearchDocumentBindProperty, value);
+        }
+
+        public static readonly DependencyProperty DocumentBindProperty =
+            DependencyProperty.RegisterAttached("DocumentBind",
+                typeof(TextBindProperty),
+                typeof(RichTextBoxHelper),
+                new FrameworkPropertyMetadata
+                {
+                    BindsTwoWayByDefault = true,
+                    PropertyChangedCallback = (obj, e) =>
+                    {
+                        RichTextBox richTextBox = obj as RichTextBox;
+                        TextBindProperty bindItem = e.NewValue as TextBindProperty;
+                        if (richTextBox != null && bindItem != null)
+                        {
+                            richTextBox.Document = GetFlowDocument(bindItem.TextContent.Trim(), bindItem.SearchWord, bindItem.HighLightColor);
+                        }
+                    }
+                });
+
+        public static readonly DependencyProperty OutlineSearchDocumentBindProperty =
+            DependencyProperty.RegisterAttached("OutlineSearchDocumentBind",
+                typeof(OutlineNode),
+                typeof(RichTextBoxHelper),
+                new FrameworkPropertyMetadata
+                {
+                    BindsTwoWayByDefault = false,
+                    PropertyChangedCallback = (obj, e) =>
+                    {
+                        RichTextBox richTextBox = obj as RichTextBox;
+                        OutlineNode bindItem = e.NewValue as OutlineNode;
+                       
+                        if (richTextBox != null )
+                        {
+                           // richTextBox.Document = GetOutlineFlowDocument(bindItem.outline.Title, searchWord, Color.FromArgb(0x99, 0xFF, 0xF7, 0x00));
+                           /* if (richTextBox.Document.Name!="nodata") {
+                                richTextBox.Visibility = Visibility.Collapsed;
+                            }*/
+                        }
+                    }
+                });
+        public static FlowDocument GetOutlineFlowDocument(string content, string keyword, Color textColor)
+        {
+            FlowDocument Document = new FlowDocument();
+            Paragraph textPara = new Paragraph();
+            Document.Blocks.Add(textPara);
+            List<int> indexList = new List<int>();
+            content = Regex.Replace(content, "[\r\n]", " ");
+            if (keyword.Length > 0)
+            {
+                for (int i = 0; i < content.Length && i >= 0;)
+                {
+                    i = content.IndexOf(keyword, i, StringComparison.OrdinalIgnoreCase);
+                    if (i == -1)
+                    {
+                        break;
+                    }
+                    if (indexList.Contains(i) == false)
+                    {
+                        indexList.Add(i);
+                    }
+                    i += keyword.Length;
+                }
+            }
+            List<string> splitList = new List<string>();
+            int lastIndex = -1;
+            foreach (int index in indexList)
+            {
+                string prevStr = string.Empty;
+                if (lastIndex == -1)
+                {
+                    prevStr = content.Substring(0, index);
+                    //Document.Name = "nodata";
+                }
+                else
+                {
+                    prevStr = content.Substring(lastIndex + keyword.Length, index - lastIndex - 1);
+                }
+                if (prevStr != string.Empty)
+                {
+                    splitList.Add(prevStr);
+                }
+
+                splitList.Add(content.Substring(index, keyword.Length));
+                lastIndex = index;
+            }
+            if (indexList.Count > 0)
+            {
+                lastIndex = indexList[indexList.Count - 1];
+                if (content.Length > lastIndex + keyword.Length)
+                {
+                    splitList.Add(content.Substring(lastIndex + keyword.Length));
+                }
+            }
+            TextBlock addBlock = new TextBlock();
+            if (splitList.Count == 0)
+            {
+                Run textRun = new Run(content);
+                addBlock.Inlines.Add(textRun);
+            }
+            else
+            {
+                foreach (string textappend in splitList)
+                {
+                    Run textRun = new Run(textappend);
+                    if (textappend.Equals(keyword, StringComparison.OrdinalIgnoreCase))
+                    {
+                        textRun.Background = new SolidColorBrush(textColor);
+                    }
+                    addBlock.Inlines.Add(textRun);
+                }
+            }
+            addBlock.TextTrimming = TextTrimming.CharacterEllipsis;
+            textPara.Inlines.Add(addBlock);
+
+            return Document;
+        }
+
+        public static FlowDocument GetFlowDocument(string content, string keyword, Color textColor)
+        {
+            FlowDocument Document = new FlowDocument();
+            Paragraph textPara = new Paragraph();
+            Document.Blocks.Add(textPara);
+            List<int> indexList = new List<int>();
+            content = Regex.Replace(content, "[\r\n]", " ");
+            if (keyword.Length > 0)
+            {
+                for (int i = 0; i < content.Length && i >= 0;)
+                {
+                    i = content.IndexOf(keyword, i, StringComparison.OrdinalIgnoreCase);
+                    if (i == -1)
+                    {
+                        break;
+                    }
+                    if (indexList.Contains(i) == false)
+                    {
+                        indexList.Add(i);
+                    }
+                    i += keyword.Length;
+                }
+            }
+            List<string> splitList = new List<string>();
+            int lastIndex = -1;
+            foreach (int index in indexList)
+            {
+                string prevStr = string.Empty;
+                if (lastIndex == -1)
+                {
+                    prevStr = content.Substring(0, index);
+                }
+                else
+                {
+                    prevStr = content.Substring(lastIndex + keyword.Length, index - lastIndex - 1);
+                }
+                if (prevStr != string.Empty)
+                {
+                    splitList.Add(prevStr);
+                }
+
+                splitList.Add(content.Substring(index, keyword.Length));
+                lastIndex = index;
+            }
+            if (indexList.Count > 0)
+            {
+                lastIndex = indexList[indexList.Count - 1];
+                if (content.Length > lastIndex + keyword.Length)
+                {
+                    splitList.Add(content.Substring(lastIndex + keyword.Length));
+                }
+            }
+            TextBlock addBlock = new TextBlock();
+            foreach (string textappend in splitList)
+            {
+                Run textRun = new Run(textappend);
+                if (textappend.Equals(keyword, StringComparison.OrdinalIgnoreCase))
+                {
+                    textRun.Background = new SolidColorBrush(textColor);
+                }
+                addBlock.Inlines.Add(textRun);
+                }
+            addBlock.TextTrimming = TextTrimming.CharacterEllipsis;
+            textPara.Inlines.Add(addBlock);
+
+            return Document;
+        }
+
+    }
+}

+ 10 - 0
PDF Office/PDF Office.csproj

@@ -226,6 +226,7 @@
     <Compile Include="DataConvert\PropertyPanelVisible.cs" />
     <Compile Include="DataConvert\StringToVisibleConvert.cs" />
     <Compile Include="DataConvert\UnVisivleConvert.cs" />
+    <Compile Include="DataConvert\WidthConvert.cs" />
     <Compile Include="EventAggregators\EditToolsEvent.cs" />
     <Compile Include="EventAggregators\PageEditNotifyEvent.cs" />
     <Compile Include="EventAggregators\PageEditRefreshEvent.cs" />
@@ -235,6 +236,7 @@
     <Compile Include="Helper\DragDropHelper.cs" />
     <Compile Include="Helper\HomePageEditHelper.cs" />
     <Compile Include="Helper\PasswordBoxHelper.cs" />
+    <Compile Include="Helper\RichTextBoxHelper.cs" />
     <Compile Include="Helper\SDKLisenceHelper.cs" />
     <Compile Include="Helper\PictureConverter.cs" />
     <Compile Include="Helper\SetterAction.cs" />
@@ -303,6 +305,7 @@
     </Compile>
     <Compile Include="ViewModels\BOTA\BookmarkContentViewModel.cs" />
     <Compile Include="ViewModels\BOTA\OutLineControlViewModel.cs" />
+    <Compile Include="ViewModels\BOTA\SearchContentViewModel.cs" />
     <Compile Include="ViewModels\Dialog\BOTA\AddBookmarkDialogViewModel.cs" />
     <Compile Include="ViewModels\Dialog\BOTA\BookmarkInfoDialogViewModel.cs" />
     <Compile Include="ViewModels\EditTools\Background\BackgroundContentViewModel.cs" />
@@ -404,6 +407,9 @@
     <Compile Include="Views\BOTA\OutLineControl.xaml.cs">
       <DependentUpon>OutLineControl.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Views\BOTA\SearchContent.xaml.cs">
+      <DependentUpon>SearchContent.xaml</DependentUpon>
+    </Compile>
     <Compile Include="Views\BottomToolContent.xaml.cs">
       <DependentUpon>BottomToolContent.xaml</DependentUpon>
     </Compile>
@@ -809,6 +815,10 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="Views\BOTA\SearchContent.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
     <Page Include="Views\BottomToolContent.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>

+ 1 - 1
PDF Office/ViewModels/BOTA/BOTAContentViewModel.cs

@@ -68,7 +68,7 @@ namespace PDF_Office.ViewModels.BOTA
             viewNameByTabItem.Add("TabItemOutLine", "OutLineControl");
             viewNameByTabItem.Add("TabItemBookMark", "BookmarkContent");
             viewNameByTabItem.Add("TabItemAnnotation", "");
-            viewNameByTabItem.Add("TabItemSearch", "");
+            viewNameByTabItem.Add("TabItemSearch", "SearchContent");
             viewNameByTabItem.Add("TabItemForm", "");
             viewNameByTabItem.Add("TabItemSign", "");
         }

+ 170 - 0
PDF Office/ViewModels/BOTA/SearchContentViewModel.cs

@@ -0,0 +1,170 @@
+using ComPDFKit.PDFPage;
+using ComPDFKitViewer.PdfViewer;
+using PDF_Office.Model;
+using PDF_Office.Views.BOTA;
+using Prism.Commands;
+using Prism.Mvvm;
+using Prism.Regions;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+using System.Windows.Media;
+using System.Windows.Threading;
+
+namespace PDF_Office.ViewModels.BOTA
+{
+     class SearchContentViewModel : BindableBase, INavigationAware
+    {
+        public PDFTextSearch textSearch;
+        private ObservableCollection<TextSearchBindItem> _searchResults = new /*ObservableCollection*/ObservableCollection<TextSearchBindItem>();
+
+        public ObservableCollection<TextSearchBindItem> searchResults
+        {
+            get { return _searchResults; }
+            set { SetProperty(ref _searchResults, value); }
+        }
+        public List<TextSearchBindItem> lists;
+        public DelegateCommand<object> SearchTextCommand { get; set; }
+        public DelegateCommand<object> SearchChangedCommand { get; set; }
+        
+        public SearchContentViewModel()
+        {
+           InitVariable();
+           InitCommand();
+           BindEvent();
+           lists = new List<TextSearchBindItem>();
+        }
+
+        private void InitVariable()
+        {
+            textSearch = new PDFTextSearch();
+          
+            ICollectionView groupView = CollectionViewSource.GetDefaultView(searchResults);
+            groupView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(TextSearchBindItem.ShowPageIndex)));
+        }
+
+        private  void InitCommand()
+        {
+            SearchTextCommand = new DelegateCommand<object>(SearchText);
+            SearchChangedCommand = new DelegateCommand<object>(SearchChanged);
+        }
+
+        private void BindEvent()
+        {
+            textSearch.SearchPercentHandler += TextSearch_SearchPercentHandler;
+            textSearch.SearchCompletedHandler += TextSearch_SearchCompletedHandler;
+        }
+
+        private void TextSearch_SearchCompletedHandler(object sender, TextSearchResult e)
+        {
+            issearched = true;
+        }
+        bool issearched = true;
+        private bool cancelTask = false;
+        private void TextSearch_SearchPercentHandler(object sender, TextSearchResult e)
+        {
+
+            if (cancelTask == false)
+            {
+                // EmptyPanel.Visibility = Visibility.Collapsed;
+                string keywords = "1";//SearchControlItem.GetSearchWords();
+                                      //PercentBar.Value = e.Percent;
+                if (e.Items.ContainsKey(e.CurrentPage))
+                {
+                    {
+                        TextSearchBindItem addItem = new TextSearchBindItem();
+                        addItem.PageCount = e.Items[e.CurrentPage].Count;
+                        addItem.ShowPageIndex = e.CurrentPage;
+                        // percentResults.Add(addItem);
+                    }
+                    {
+                        foreach (TextSearchItem item in e.Items[e.CurrentPage])
+                        {
+                            TextSearchBindItem addItem = new TextSearchBindItem();
+                            addItem.BindProperty.PageIndex = item.PageIndex;
+                            addItem.BindProperty.TextContent = item.TextContent;
+                            addItem.BindProperty.TextRect = item.TextRect;
+                            addItem.BindProperty.SearchWord = keywords;
+                            addItem.BindProperty.HighLightColor = Color.FromArgb(0x99, 0xFF, 0xF7, 0x00);
+                            addItem.BindProperty.PageRotate = item.PageRotate;
+                            lists.Add(addItem);
+                        }
+                    }
+                    //foreach (TextSearchBindItem item in percentResults)
+                    //{
+                    //    item.PageMaxCount = e.PageMaxCount;
+                    //}
+
+                }
+                // TotalRecord.Text = e.TotalCount.ToString();
+            }
+        }
+
+        private async void SearchText(object obj)
+        {
+
+            if (PDFViewer != null && textSearch != null)
+            {
+                issearched = false;
+                   C_Search_Options option = C_Search_Options.Search_Case_Insensitive;
+                textSearch.TextSearchDocument = PDFViewer.Document;
+                searchResults.Clear();
+                lists.Clear();
+                var sourceText = "1";
+                textSearch.SearchText(sourceText, option);
+            }
+            while (issearched == false)
+                await Task.Delay(10);
+
+            foreach (var item in lists)
+                searchResults.Add(item);
+        }
+
+
+        private void SearchChanged(object obj)
+        {
+
+            if (PDFViewer != null && textSearch != null)
+            {
+                TextSearchBindItem currentItem = obj as TextSearchBindItem;
+                if (currentItem != null && PDFViewer != null)
+                {
+                    List<TextSearchItem> pageTextList = new List<TextSearchItem>();
+                    pageTextList.Add(new TextSearchItem()
+                    {
+                        PageIndex = currentItem.BindProperty.PageIndex,
+                        TextRect = currentItem.BindProperty.TextRect,
+                        TextContent = currentItem.BindProperty.TextContent,
+                        PageRotate = currentItem.BindProperty.PageRotate
+                    });
+                    PDFViewer.SetPageSelectText(pageTextList, new SolidColorBrush(Color.FromArgb(0x99, 0xFF, 0xF7, 0x00)));
+                }
+            }
+        }
+
+        public bool IsNavigationTarget(NavigationContext navigationContext)
+        {
+            return true;
+        }
+
+        public void OnNavigatedFrom(NavigationContext navigationContext)
+        {
+            return;
+        }
+
+        private CPDFViewer PDFViewer;
+        public void OnNavigatedTo(NavigationContext navigationContext)
+        {
+            navigationContext.Parameters.TryGetValue<CPDFViewer>(ParameterNames.PDFViewer, out PDFViewer);
+            if (PDFViewer != null)
+            {
+
+            }
+        }
+    }
+}

+ 178 - 0
PDF Office/Views/BOTA/SearchContent.xaml

@@ -0,0 +1,178 @@
+<UserControl x:Class="PDF_Office.Views.BOTA.SearchContent"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:PDF_Office.Views.BOTA"
+             xmlns:prism="http://prismlibrary.com/"
+             prism:ViewModelLocator.AutoWireViewModel="True"
+             xmlns:bota="clr-namespace:PDF_Office.ViewModels.BOTA"
+             d:DataContext="{d:DesignInstance Type=bota:SearchContentViewModel}"
+             xmlns:helper="clr-namespace:PDF_Office.Helper"
+              xmlns:convert="clr-namespace:PDF_Office.DataConvert"
+             xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
+             mc:Ignorable="d" 
+             d:DesignHeight="450" d:DesignWidth="800">
+   
+    <UserControl.Resources>
+        <convert:WidthConvert x:Key="WidthConvert"/>
+        
+        
+        
+        <Style x:Key="ListViewItemGraySelectStyle" TargetType="{x:Type ListViewItem}">
+            <Setter Property="UIElement.SnapsToDevicePixels"
+            Value="True" />
+            <Setter Property="Control.Padding"
+            Value="4,1" />
+            <Setter Property="Control.HorizontalContentAlignment">
+                <Setter.Value>
+                    <Binding Path="HorizontalContentAlignment"
+                     RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl, AncestorLevel=1}" />
+                </Setter.Value>
+            </Setter>
+            <Setter Property="Control.VerticalContentAlignment">
+                <Setter.Value>
+                    <Binding Path="VerticalContentAlignment"
+                     RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl, AncestorLevel=1}" />
+                </Setter.Value>
+            </Setter>
+            <Setter Property="Panel.Background"
+            Value="#00FFFFFF" />
+            <Setter Property="Border.BorderBrush"
+            Value="#00FFFFFF" />
+            <Setter Property="Border.BorderThickness"
+            Value="1" />
+            <Setter Property="FrameworkElement.FocusVisualStyle">
+                <Setter.Value>
+                    <Style TargetType="{x:Type IFrameworkInputElement}">
+                        <Setter Property="Control.Template">
+                            <Setter.Value>
+                                <ControlTemplate>
+                                    <Rectangle Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"
+                                       StrokeThickness="1"
+                                       StrokeDashArray="1 2"
+                                       Margin="2"
+                                       SnapsToDevicePixels="True" />
+                                </ControlTemplate>
+                            </Setter.Value>
+                        </Setter>
+                    </Style>
+                </Setter.Value>
+            </Setter>
+            <Setter Property="Control.Template">
+                <Setter.Value>
+                    <ControlTemplate TargetType="{x:Type ListViewItem}">
+                        <Border BorderThickness="{TemplateBinding Border.BorderThickness}"
+                        Padding="{TemplateBinding Control.Padding}"
+                        BorderBrush="{TemplateBinding Border.BorderBrush}"
+                        Background="{TemplateBinding Panel.Background}"
+                        Name="Bd"
+                        SnapsToDevicePixels="True">
+                            <ContentPresenter Content="{TemplateBinding ContentControl.Content}"
+                                      ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
+                                      ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
+                                      HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
+                                      VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
+                                      SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
+                        </Border>
+                        <ControlTemplate.Triggers>
+                            <MultiTrigger>
+                                <MultiTrigger.Conditions>
+                                    <Condition Property="UIElement.IsMouseOver" Value="True" />
+                                </MultiTrigger.Conditions>
+                                <Setter Property="Panel.Background" TargetName="Bd" Value="#1A000000" />
+                                <Setter Property="Border.BorderBrush" TargetName="Bd" Value="#1A000000" />
+                            </MultiTrigger>
+                            <MultiTrigger>
+                                <MultiTrigger.Conditions>
+                                    <Condition Property="Selector.IsSelectionActive" Value="False" />
+                                    <Condition Property="Selector.IsSelected" Value="True" />
+                                </MultiTrigger.Conditions>
+                                <Setter Property="Panel.Background" TargetName="Bd" Value="#1A477EDE" />
+                                <Setter Property="Border.BorderBrush" TargetName="Bd" Value="#1A477EDE" />
+                            </MultiTrigger>
+                            <MultiTrigger>
+                                <MultiTrigger.Conditions>
+                                    <Condition Property="Selector.IsSelectionActive" Value="True" />
+                                    <Condition Property="Selector.IsSelected" Value="True" />
+                                </MultiTrigger.Conditions>
+                                <Setter Property="Panel.Background" TargetName="Bd" Value="#1A477EDE" />
+                                <Setter Property="Border.BorderBrush" TargetName="Bd" Value="#1A477EDE" />
+                            </MultiTrigger>
+                            <Trigger Property="UIElement.IsEnabled"  Value="False">
+                                <Setter Property="TextElement.Foreground" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
+                            </Trigger>
+                        </ControlTemplate.Triggers>
+                    </ControlTemplate>
+                </Setter.Value>
+            </Setter>
+        </Style>
+    </UserControl.Resources>
+    <Grid Background="#F3F3F3" Width="200">
+        <Grid.RowDefinitions>
+            <RowDefinition Height="auto"/>
+            <RowDefinition Height="auto"/>
+            <RowDefinition/>
+        </Grid.RowDefinitions>
+
+        <Grid Height="48" >
+            <TextBlock Text="查找"  HorizontalAlignment="Left" VerticalAlignment="Center"/>
+            <Button Content="完成" HorizontalAlignment="Right" VerticalAlignment="Center"/>
+        </Grid>
+
+        <Grid Height="48"  Grid.Row="1">
+            <TextBox Width="150" HorizontalAlignment="Left"/>
+
+            <Button Content="完成" HorizontalAlignment="Right" VerticalAlignment="Center" Command="{Binding SearchTextCommand}"/>
+        </Grid>
+
+        <Grid Grid.Row="2">
+            <ListView Grid.Row="1" Name="SearchResultList" VirtualizingPanel.IsVirtualizingWhenGrouping="True" 
+                      ItemsSource="{Binding searchResults,Mode=OneWay}"
+                              BorderThickness="0" ItemContainerStyle="{StaticResource ListViewItemGraySelectStyle}" 
+                              SelectionChanged="SearchResultList_SelectionChanged"
+                              ScrollViewer.HorizontalScrollBarVisibility="Hidden">
+                <ListView.GroupStyle>
+                    <GroupStyle>
+                        <GroupStyle.HeaderTemplate>
+                            <DataTemplate>
+                                <StackPanel Background="#E2E3E6" Height="24">
+                                    <TextBlock Padding="0,4,12,4" VerticalAlignment="Stretch" TextAlignment="Center" HorizontalAlignment="Right" FontWeight="SemiBold" FontSize="12" Text="{Binding Name}" 
+                                                        FontFamily="Segoe UI" Foreground="#666666 "/>
+                                </StackPanel>
+                            </DataTemplate>
+                        </GroupStyle.HeaderTemplate>
+                        <GroupStyle.Panel>
+                            <ItemsPanelTemplate>
+                                <VirtualizingStackPanel/>
+                            </ItemsPanelTemplate>
+                        </GroupStyle.Panel>
+                    </GroupStyle>
+                </ListView.GroupStyle>
+                <ListView.ItemsPanel>
+                    <ItemsPanelTemplate>
+                        <VirtualizingStackPanel Background="White" Margin="-5,0,0,0"></VirtualizingStackPanel>
+                    </ItemsPanelTemplate>
+                </ListView.ItemsPanel>
+                <ListView.ItemTemplate>
+                    <ItemContainerTemplate>
+                        <StackPanel>
+                            <RichTextBox Background="Transparent" Foreground="#000000" FontFamily="Segoe UI" FontSize="14" IsReadOnly="True" BorderThickness="0" 
+                                                 Padding="12,6,10,6" VerticalContentAlignment="Center" VerticalAlignment="Center"
+                                         helper:RichTextBoxHelper.DocumentBind="{Binding BindProperty}"
+                                         Width="{Binding ElementName=SearchResultList,Path=ActualWidth,Converter={StaticResource WidthConvert}}"
+                                                  IsHitTestVisible="False" >
+                            </RichTextBox>
+                        </StackPanel>
+                    </ItemContainerTemplate>
+                </ListView.ItemTemplate>
+
+                <i:Interaction.Triggers>
+                    <i:EventTrigger EventName="SelectionChanged">
+                        <i:InvokeCommandAction Command="{Binding SearchChangedCommand}" CommandParameter="{Binding ElementName=SearchResultList,Path=SelectedItem}"/>
+                    </i:EventTrigger>
+                </i:Interaction.Triggers>
+            </ListView>
+        </Grid>
+    </Grid>
+</UserControl>

+ 72 - 0
PDF Office/Views/BOTA/SearchContent.xaml.cs

@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace PDF_Office.Views.BOTA
+{
+    public class TextSearchBindItem : INotifyPropertyChanged
+    {
+        public int ShowPageIndex { get { return BindProperty.PageIndex + 1; } set { BindProperty.PageIndex = value; } }
+        public TextBindProperty BindProperty { get; set; }
+        public TextSearchBindItem()
+        {
+            BindProperty = new TextBindProperty();
+        }
+
+        public int PageCount { get; set; }
+        private int _pageMaxCount;
+        public int PageMaxCount { get { return _pageMaxCount; } set { _pageMaxCount = value; OnPropertyChanged("Percent"); } }
+
+        public double Percent { get { if (PageMaxCount > 0 && PageCount >= 0) return (double)PageCount / (double)PageMaxCount; return 0; } }
+
+        public event PropertyChangedEventHandler PropertyChanged;
+        protected void OnPropertyChanged([CallerMemberName] string name = null)
+        {
+            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+        }
+    }
+
+
+    public class TextBindProperty
+    {
+        public int PageIndex { get; set; }
+        public string TextContent { get; set; }
+        public Color HighLightColor { get; set; }
+        public string SearchWord { get; set; }
+        public Rect TextRect { get; set; }
+        public int PageRotate { get; set; }
+    }
+    /// <summary>
+    /// SearchContent.xaml 的交互逻辑
+    /// </summary>
+    public partial class SearchContent : UserControl
+    {
+       // private ObservableCollection<TextSearchBindItem> searchResults;
+        public SearchContent()
+        {
+            InitializeComponent();
+       //     searchResults = new ObservableCollection<TextSearchBindItem>();
+        //    ICollectionView groupView = CollectionViewSource.GetDefaultView(searchResults);
+        //    groupView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(TextSearchBindItem.ShowPageIndex)));
+        }
+
+        private void SearchResultList_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+
+        }
+    }
+}