This project is read-only.

How To Integrate Full Text Search

The following step-by-step tutorial demonstrates how to integrate full text search with your document viewer using Visual Studio 2010. The download link for the complete source code of this tutorial is available at the bottom of this page.

1) Open Visual Studio 2010 and create a new Silverlight 4 application

2) Use NuGet to add references to the DocumentToolkit package (see How To Install Document Toolkit using NuGet).

3) Add an existing XPS document to the project as content. Right-click the project, select Add > Existing Item... and select an XPS document from disk. Make sure you set the Build Action to Content, which causes the document to appear as file in the XAP package.

You can use NuGet to install sample documents from the DocumentToolkit.SampleDocs package.

4) Open the MainPage.xaml and add a DocumentDataSource and DocumentViewer.

<Grid x:Name="LayoutRoot" Background="White">
  <Grid.ColumnDefinitions>
    <ColumnDefinition />
    <ColumnDefinition Width="200" />
  </Grid.ColumnDefinitions>
  <Grid.RowDefinitions>
    <RowDefinition />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>
        
  <doc:DocumentDataSource x:Name="DataSource" LoadError="DataSource_LoadError"
                          SearchCompleted="DataSource_SearchCompleted" />
  <doc:DocumentViewer x:Name="Viewer" DocumentDataSource="{Binding ElementName=DataSource}">
    <doc:DocumentViewer.ViewMode>
      <doc:ViewMode ScaleMode="FitPage" />
    </doc:DocumentViewer.ViewMode>
    <doc:DocumentViewer.Selection>
      <doc:TextSelection IsEnabled="True" />
    </doc:DocumentViewer.Selection>
  </doc:DocumentViewer>

The DocumentViewer instance has a view mode set so it automatically scales and also has an enabled text selection.

5) In the code-behind add the load XPS package logic and implement the datasource LoadError and SearchCompleted event handlers:

using FirstFloor.Documents.Controls;
using FirstFloor.Documents.IO;
using FirstFloor.Documents.Search;

public MainPage()
{
  InitializeComponent();

  this.DataSource.PackageReader = new DefaultPackageReader(new Uri("Document Toolkit.xps", UriKind.Relative));
}

private void DataSource_LoadError(object sender, ErrorEventArgs e)
{
  MessageBox.Show(e.Error.ToString());
}

private void DataSource_SearchCompleted(object sender, AsyncCompletedEventArgs e)
{
  if (!e.Cancelled && e.Error != null) {
    MessageBox.Show(e.Error.ToString());
  }
}

6) Now back in the MainPage.xaml we want to add a search result list. The list is bound to the SearchResults collection exposed by the DocumentDataSource.

<ListBox x:Name="SearchResults" Grid.Column="1" SelectionChanged="SearchResults_SelectionChanged"
         ItemsSource="{Binding SearchResults, ElementName=DataSource}"
         DisplayMemberPath="Value"  />

The list box simply displays the value of the search result. You could enhance the result list by using an item datatemplate displaying additional result data such as page number and text index.

7) Handle the SelectionChanged event in the code behind, so that the search result is selected in the document viewer and brought into view:

private void SearchResults_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
  var result = this.SearchResults.SelectedItem as SearchResult;
  if (result != null) {
    // select
    this.Viewer.Selection.Select(result.Range);

    // bring into view
    this.Viewer.BringIntoView(result.Range.Start);
  }
}

8) All that is left to do is add a search text box and a search button. The DocumentDataSource exposes a SearchCommand that is used to start a full text search operation. The SearchCommand parameter must contain a SearchQuery instance providing search settings. In the code snippet below a SearchQuery instance is provided using the RegexSearchProvider to perform full text search using regular expressions:

<StackPanel Orientation="Horizontal" Grid.Row="1" Grid.ColumnSpan="2" HorizontalAlignment="Center">
  <TextBox x:Name="SearchText" Width="150" Margin="4" />
  <Button Content="Search" Margin="4" Command="{Binding SearchCommand, ElementName=DataSource}">
    <Button.CommandParameter>
      <doc:SearchQuery TextToSearch="{Binding Text, ElementName=SearchText}">
        <!-- using the built-in regex search provider -->
        <doc:SearchQuery.SearchProvider>
          <doc:RegexSearchProvider Options="IgnoreCase" />
        </doc:SearchQuery.SearchProvider>
      </doc:SearchQuery>
    </Button.CommandParameter>
  </Button>
</StackPanel>

Compile and run the project. Enter a search phrase and hit search, the search results list will be populated and selecting a search result causes the document viewer to select the phrase.

Tutorial source code: FullTextSearch.zip

Last edited Jul 4, 2011 at 8:26 PM by kozw, version 5

Comments

No comments yet.