Document Library for UWP | ComponentOne
PdfDocumentSource for UWP / Features / Text Search
In This Topic
    Text Search
    In This Topic

    PDFDocumentSource allows you to implement text search in a PDF file by matching the search criteria and examining all the words stored in the file through C1TextSearchManager class, member of C1.Xaml.Document namespace. The class provides various methods, such as FindStart to find the first occurrence, FindNext to find the next occurrence, and FindPrevious to find the previous occurrence of the searched text. You can use C1FindTextParams(string text, bool wholeWord, bool matchCase) method to initialize a new instance of C1FindTextParams class with the following parameters:

    The following image shows the word searched in a PDF file and the list of matches as search results.

    To search text programmatically

    In this sample code, we use the FindStart method on the C1TextSearchManager to find instances of the search text.

    Step 1: Setting up the application

    1. Add C1PdfDocumentSource, OpenFileDialog, ListView, two TextBox, and three Button controls to the Form.
    2. Add columns to the ListView control by adding the following XAML code.
      XAML
      Copy Code
      <ListView x:Name="listView1" HorizontalAlignment="Left" Width="585" Margin="10,150,0,10">
          <ListView.HeaderTemplate>
              <DataTemplate>
                  <StackPanel Orientation="Horizontal">
                      <TextBlock Text="#" Margin="5,5,0,0"></TextBlock>
                      <TextBlock Text="Page" Margin="15,5,0,0"></TextBlock>
                      <TextBlock Text="Bounds" Margin="40,5,0,0"></TextBlock>
                      <TextBlock Text="Position" Margin="40,5,0,0"></TextBlock>
                      <TextBlock Text="NearText" Margin="40,5,0,0"></TextBlock>
                  </StackPanel>
              </DataTemplate>
          </ListView.HeaderTemplate>
          <ListView.ItemTemplate>
              <DataTemplate>
                  <StackPanel Orientation="Horizontal">
                      <TextBlock Text="{Binding ID}" Margin="5,0,0,0"></TextBlock>
                      <TextBlock Text="{Binding Page}" Margin="15,0,0,0"></TextBlock>
                      <TextBlock Text="{Binding Bounds}" Margin="30,5,0,0"></TextBlock>
                      <TextBlock Text="{Binding Position}" Margin="30,5,0,0"></TextBlock>
                      <TextBlock Text="{Binding NearText}" Margin="30,5,0,0"></TextBlock>
                  </StackPanel>
              </DataTemplate>
          </ListView.ItemTemplate>
      </ListView>
      

    Step 2: Browse and search text in a PDF file

    1. Switch to the code view and add the following namespace.
      Imports C1.Xaml.Document
      
      using C1.Xaml.Document;
      
    2. Add a PDF file to the project. In our case, we have used PDF file named DefaultDocument.pdf from the product sample.
    3. Add the following code to create an instance of C1TextSearchManager and StorageFile class, initialize the instance of C1PDFDocumentSource, and declare a variable, loadedFile, of string type.
      ' C1TextSearchManager instance used by the search.
      Private tsm As C1TextSearchManager
      
      ' File name of the currently loaded document.
      Private loadedFile As String = Nothing
      
      Private pds As New C1PdfDocumentSource()
      Private file As StorageFile
      
      // C1TextSearchManager instance used by the search.
      C1TextSearchManager tsm;
      
      // File name of the currently loaded document.
      private string loadedFile = null;
      
      C1PdfDocumentSource pds = new C1PdfDocumentSource();
      StorageFile file;
      
    4. Add the following code below the InitializeComponent() method.
      ' Create and initialize the C1TextSearchManager:
      tsm = New C1TextSearchManager(pds)
      tsm.FoundPositionsChanged += Tsm_FoundPositionsChanged
      
      'UseSystemRendering is set to false to allow 
      'text search using built-in PDF renderer
      pds.UseSystemRendering = False
      
      // Create and initialize the C1TextSearchManager:
      tsm = new C1TextSearchManager(pds);
      tsm.FoundPositionsChanged += Tsm_FoundPositionsChanged;
      
      //UseSystemRendering is set to false to allow 
      //text search using built-in PDF renderer
      pds.UseSystemRendering = false;
      
    5. Add the following code to directly access the PDF file in the app package.
      'use ms-aapx protocol to access PDF file in the app package
      file = Await StorageFile.GetFileFromApplicationUriAsync(New Uri _
             ("ms-appx:///DefaultDocument.pdf"))
      
      ' Use sample file:
      tbFile.Text = Path.GetFullPath(file.Name)
      
      //use ms-aapx protocol to access PDF file in the app package
      file = await StorageFile.GetFileFromApplicationUriAsync(new
             Uri("ms-appx:///DefaultDocument.pdf"));
      
      // Use sample file:
      tbFile.Text = Path.GetFullPath(file.Name);
      
    6. Add the following code to the click event of btnFile to open the dialog box for browsing and opening a PDF file.
      Private Sub btnFile_Click(sender As Object, e As RoutedEventArgs)
         Dim dialog As New FileOpenPicker()
         dialog.ViewMode = PickerViewMode.Thumbnail
         dialog.SuggestedStartLocation = PickerLocationId.Desktop
         dialog.FileTypeFilter.Add(".pdf")
      
         ' Allow the user to choose a PDF file to search.
         file = Await dialog.PickSingleFileAsync()
         If file IsNot Nothing Then
             ' Application now has read/write access to the picked file
             tbFile.Text = file.Name
         Else
             tbFile.Text = "Operation cancelled."
         End If
      End Sub
      
      private async void btnFile_Click(object sender, RoutedEventArgs e)
      {
          FileOpenPicker dialog = new FileOpenPicker();
          dialog.ViewMode = PickerViewMode.Thumbnail;
          dialog.SuggestedStartLocation = PickerLocationId.Desktop;
          dialog.FileTypeFilter.Add(".pdf");
      
          // Allow the user to choose a PDF file to search.
          file = await dialog.PickSingleFileAsync();
          if (file != null)
          {
              // Application now has read/write access to the picked file
              tbFile.Text = file.Name;
          }
          else
          {
              tbFile.Text = "Operation cancelled.";
          }
      }
      
    7. Add the following code to the click event of btnFind to start the text search.
      ' Perform the text search.
      Private Sub btnFind_Click(sender As Object, e As RoutedEventArgs)
         ' Load the specified PDF file into c1PdfDocumentSource1, do the search:
         Try
              Await pds.LoadFromFileAsync(file)
                loadedFile = tbFile.Text
         Catch ex As Exception
              Dim dialog = New MessageDialog(ex.Message)
              Await dialog.ShowAsync()
                Return
         End Try
      
         ' Clear the previously found positions, if any:
         listView1.Items.Clear()
      
         ' Init C1FindTextParams with values provided by the user:
         Dim ftp As New C1FindTextParams(tbFind.Text, True, False)
      
         ' Do the search (FindStartAsync is also available):
         tsm.FindStart(0, True, ftp)
      End Sub
      
      // Perform the text search.
      private async void btnFind_Click(object sender, RoutedEventArgs e)
      {
          // Load the specified PDF file into c1PdfDocumentSource1, do the search:
          try
          {
              await pds.LoadFromFileAsync(file);
              loadedFile = tbFile.Text;
          }
          catch (Exception ex)
          {
              var dialog = new MessageDialog(ex.Message);
              await dialog.ShowAsync();
              return;
          }
      
          // Clear the previously found positions, if any:
          listView1.Items.Clear();
      
          // Init C1FindTextParams with values provided by the user:
          C1FindTextParams ftp = new C1FindTextParams(tbFind.Text, true, false);
      
          // Do the search (FindStartAsync is also available):
          tsm.FindStart(0, true, ftp);
      }
      
    8. Add the following code to create a class named SearchItem.
      Public Class SearchItem
         Public Property ID() As Integer
            Get
               Return m_ID
            End Get
            Set
               m_ID = Value
            End Set
         End Property
      Private m_ID As Integer
         Public Property Page() As String
            Get
               Return m_Page
            End Get
            Set
               m_Page = Value
            End Set
         End Property
       Private m_Page As String
          Public Property Bounds() As String
             Get
                Return m_Bounds
             End Get
             Set
                m_Bounds = Value
             End Set
          End Property
      Private m_Bounds As String
          Public Property Position() As String
             Get
                Return m_Position
             End Get
             Set
                m_Position = Value
             End Set
          End Property
      Private m_Position As String
          Public Property NearText() As String
             Get
                Return m_NearText
             End Get
             Set
                m_NearText = Value
             End Set
          End Property
      Private m_NearText As String
      End Class
      
      public class SearchItem
      {
          public int ID { get; set; }
          public string Page { get; set; }
          public string Bounds { get; set; }
          public string Position { get; set; }
          public string NearText { get; set; }
      }
      
    9. Add the following event to update the list of found positions in the UI.
      ' Called when the FoundPositions collection on the C1TextSearchManager
      ' has changed (i.e. some new instances of the search text were found).
      ' Use this to update the list of the found positions in the UI.
      Private Sub Tsm_FoundPositionsChanged(sender As Object, e As EventArgs)
         Dim n As Integer = tsm.FoundPositions.Count
         For i As Integer = listView1.Items.Count To n - 1
             Dim fp As C1FoundPosition = tsm.FoundPositions(i)
             Dim bounds = fp.GetBounds()
      
             listView1.Items.Add(New SearchItem() With { _
                .ID = i + 1, _
                .Page = fp.GetPage().PageNo.ToString(), _
                .Bounds = String.Format("{0}, {1}, {2}, {3}", _
                          CInt(Math.Round(bounds.Left)), _
                          CInt(Math.Round(bounds.Top)), _
                          CInt(Math.Round(bounds.Width)), _
                          CInt(Math.Round(bounds.Height))), _
                .Position = fp.PositionInNearText.ToString(), _
                .NearText = fp.NearText _
              })
         Next
      End Sub
      
      // Called when the FoundPositions collection on the C1TextSearchManager
      //  has changed (i.e. some new instances of the search text were found).
      // Use this to update the list of the found positions in the UI.
      private void Tsm_FoundPositionsChanged(object sender, EventArgs e)
      {
          int n = tsm.FoundPositions.Count;
          for (int i = listView1.Items.Count; i < n; i++)
              {
                  C1FoundPosition fp = tsm.FoundPositions[i];
                  var bounds = fp.GetBounds();
      
                  listView1.Items.Add(new SearchItem
                  {
                      ID = i + 1,
                      Page = fp.GetPage().PageNo.ToString(),
                      Bounds = string.Format("{0}, {1}, {2}, {3}",
                      (int)Math.Round(bounds.Left),
                      (int)Math.Round(bounds.Top),
                      (int)Math.Round(bounds.Width),
                      (int)Math.Round(bounds.Height)),
                      Position = fp.PositionInNearText.ToString(),
                      NearText = fp.NearText
                  });
              }
      }
      

    Step 3: Build and run the project

    1. Press Ctrl+Shift+B to build the project.
    2. Press F5 to run the application.
    See Also