View PDF Annotations as a List and Navigate Using Xamarin.Forms PDF Viewer
Live Chat Icon For mobile
Live Chat Icon
Popular Categories.NET  (173).NET Core  (29).NET MAUI  (207)Angular  (109)ASP.NET  (51)ASP.NET Core  (82)ASP.NET MVC  (89)Azure  (40)Black Friday Deal  (1)Blazor  (215)BoldSign  (14)DocIO  (24)Essential JS 2  (107)Essential Studio  (200)File Formats  (66)Flutter  (132)JavaScript  (220)Microsoft  (118)PDF  (81)Python  (1)React  (100)Streamlit  (1)Succinctly series  (131)Syncfusion  (912)TypeScript  (33)Uno Platform  (3)UWP  (4)Vue  (45)Webinar  (51)Windows Forms  (61)WinUI  (68)WPF  (158)Xamarin  (161)XlsIO  (36)Other CategoriesBarcode  (5)BI  (29)Bold BI  (8)Bold Reports  (2)Build conference  (8)Business intelligence  (55)Button  (4)C#  (147)Chart  (130)Cloud  (15)Company  (443)Dashboard  (8)Data Science  (3)Data Validation  (8)DataGrid  (63)Development  (625)Doc  (8)DockingManager  (1)eBook  (99)Enterprise  (22)Entity Framework  (5)Essential Tools  (14)Excel  (40)Extensions  (22)File Manager  (7)Gantt  (18)Gauge  (12)Git  (5)Grid  (31)HTML  (13)Installer  (2)Knockout  (2)Language  (1)LINQPad  (1)Linux  (2)M-Commerce  (1)Metro Studio  (11)Mobile  (505)Mobile MVC  (9)OLAP server  (1)Open source  (1)Orubase  (12)Partners  (21)PDF viewer  (43)Performance  (12)PHP  (2)PivotGrid  (4)Predictive Analytics  (6)Report Server  (3)Reporting  (10)Reporting / Back Office  (11)Rich Text Editor  (12)Road Map  (12)Scheduler  (52)Security  (3)SfDataGrid  (9)Silverlight  (21)Sneak Peek  (31)Solution Services  (4)Spreadsheet  (11)SQL  (10)Stock Chart  (1)Surface  (4)Tablets  (5)Theme  (12)Tips and Tricks  (112)UI  (386)Uncategorized  (68)Unix  (2)User interface  (68)Visual State Manager  (2)Visual Studio  (31)Visual Studio Code  (19)Web  (589)What's new  (331)Windows 8  (19)Windows App  (2)Windows Phone  (15)Windows Phone 7  (9)WinRT  (26)
View PDF Annotations as a List and Navigate Using Xamarin.Forms PDF Viewer

View PDF Annotations as a List and Navigate Using Xamarin.Forms PDF Viewer

Annotations show additional information in a document. PDF annotations can be grouped and showcased in a list view at the application level based on the pages in which they are present. We can also easily navigate to the selected annotations in a PDF.

In this blog, we will see how to showcase the annotations in a list view and navigate to them based on our selection using our Syncfusion Xamarin PDF Viewer control.

Create a Xamarin app and add dependencies

First, create a new Xamarin app and install the following NuGet packages in it:

Create a list view item data template

Then, create a content view in the ListViewItem.xaml file to display the annotations data with the name and corresponding icon in each list view cell.

Refer to the following code example.

<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="AnnotationsListView.ListViewItem">
 <ContentView.Content>
  <StackLayout HeightRequest="40" Orientation="Horizontal">
   <Label x:Name="annotationFontIcon" Margin="10,0,0,0" VerticalOptions="Center" InputTransparent="true" BackgroundColor="Transparent" TextColor="#0076FF" FontSize="16"/>
   <Label x:Name="annotationLabel" FontSize="Medium" TextColor="Black" Padding="10,0,0,0" VerticalOptions="Center"/>
  </StackLayout>
 </ContentView.Content>
</ContentView>

Add the annotation name and its corresponding icon when the list view item’s binding context changes. This logic can be implemented in the ListViewItem partial class in the ListViewItem.xaml.cs file.

Refer to the following code example.

public partial class ListViewItem : ContentView
{
  public ListViewItem()
  {
    InitializeComponent();
    BindingContextChanged += ListViewItem_BindingContextChanged;
  }
 
  private void ListViewItem_BindingContextChanged(object sender, EventArgs e)
  {
    if (BindingContext == null)
    return;
 
    annotationFontIcon.FontFamily = FontMappingHelper.FontFamily;
 
    if (BindingContext is ShapeAnnotation annotation)
    {
      annotationLabel.Text = annotation.ShapeAnnotationType.ToString();
 
     if (annotation.ShapeAnnotationType == ShapeAnnotationType.Line)
     {
       annotationFontIcon.Text = FontMappingHelper.Line;
     }
     else if (annotation.ShapeAnnotationType == ShapeAnnotationType.Rectangle)
     {
       annotationFontIcon.Text = FontMappingHelper.Rectangle;
     }
     else if (annotation.ShapeAnnotationType == ShapeAnnotationType.Circle)
     {
       annotationFontIcon.Text = FontMappingHelper.Circle;
     }
     else if (annotation.ShapeAnnotationType == ShapeAnnotationType.Arrow)
     {
       annotationFontIcon.Text = FontMappingHelper.Arrow;
     }
     else if (annotation.ShapeAnnotationType == ShapeAnnotationType.Polygon)
     {
       annotationFontIcon.Text = FontMappingHelper.Polygon;
     }
   }
   else if (BindingContext is TextMarkupAnnotation textMarkup)
   {
     annotationLabel.Text = textMarkup.TextMarkupAnnotationType.ToString();
     if (textMarkup.TextMarkupAnnotationType == TextMarkupAnnotationType.Highlight)
     {
       annotationFontIcon.Text = FontMappingHelper.Highlight;
     }
     else if (textMarkup.TextMarkupAnnotationType == TextMarkupAnnotationType.Strikethrough)
     {
       annotationFontIcon.Text = FontMappingHelper.StrikeThrough;
     }
     else if (textMarkup.TextMarkupAnnotationType == TextMarkupAnnotationType.Underline)
     {
       annotationFontIcon.Text = FontMappingHelper.Underline;
     }
   }
   else if (BindingContext is FreeTextAnnotation freeText)
   {
     annotationLabel.Text = "Free Text";
     annotationFontIcon.Text = FontMappingHelper.EditText;
   }
   else if (BindingContext is InkAnnotation ink)
   {
     annotationLabel.Text = "Ink";
     annotationFontIcon.Text = FontMappingHelper.Ink;
   }
 }
}

In the following code example, the FontMappingHelper class represents the font icon text for the available annotations.

/// <summary>
/// Represents the font text of the annotations.
/// </summary>
public class FontMappingHelper
{
  public static string FontFamily = Device.RuntimePlatform == Device.Android ? "Final_PDFViewer_Android_FontUpdate.ttf#"
  : Device.RuntimePlatform == Device.iOS ? "Final_PDFViewer_IOS_FontUpdate"
  : "/Assets/Fonts/Final_PDFViewer_UWP_FontUpdate.ttf#Final_PDFViewer_UWP_FontUpdate";
 
  public static string Underline = Device.RuntimePlatform == Device.Android ? "\uE70d" : Device.RuntimePlatform == Device.iOS ? "\uE70c" : "\uE721";
 
  public static string StrikeThrough = Device.RuntimePlatform == Device.Android ? "\uE711" : Device.RuntimePlatform == Device.iOS ? "\uE71e" : "\uE709";
 
  public static string Highlight = Device.RuntimePlatform == Device.Android ? "\uE715" : Device.RuntimePlatform == Device.iOS ? "\uE710" : "\uE70c";
 
  public static string Ink = Device.RuntimePlatform == Device.Android ? "\uE71d" : Device.RuntimePlatform == Device.iOS ? "\uE704" : "\uE704";
 
  public static string EditText = Device.RuntimePlatform == Device.Android ? "\uE71f" : Device.RuntimePlatform == Device.iOS ? "\uE700" : "\uE71A";
 
  public static string Rectangle = Device.RuntimePlatform == Device.Android ? "\uE710" : Device.RuntimePlatform == Device.iOS ? "\uE705" : "\uE70e";
 
  public static string Circle = Device.RuntimePlatform == Device.Android ? "\uE714" : Device.RuntimePlatform == Device.iOS ? "\uE71f" : "\uE717";
 
  public static string Line = Device.RuntimePlatform == Device.Android ? "\uE703" : Device.RuntimePlatform == Device.iOS ? "\uE717" : "\uE71b";
 
  public static string Arrow = Device.RuntimePlatform == Device.Android ? "\uE701" : Device.RuntimePlatform == Device.iOS ? "\uE712" : "\uE70a";
 
  public static string Polygon = Device.RuntimePlatform == Device.Android ? "\uE712" : Device.RuntimePlatform == Device.iOS ? "\uE70D" : "\uE715";
 
}

Refer to the following screenshot.
Annotations Font Icons

Note: The listed font files are shipped with the GitHub example.

Organize PDF Viewer, Navigation Drawer, and ListView

Let’s create a main content page in the MainPage.xaml and add the Xamarin.Forms PDF Viewer and Navigation Drawer components as the children to it. Then, we add the Xamarin.Forms ListView component as a child to the Navigation Drawer and set the appearance for each cell in the list view with the created data template.

Next, set the PDF Viewer component as the binding context for the ListView component and bind the PDF Viewer’s Annotations collection property as the ItemSource to it.

Refer to the following code example.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:AnnotationsListView"
             xmlns:navigationdrawer="clr-namespace:Syncfusion.SfNavigationDrawer.XForms;assembly=Syncfusion.SfNavigationDrawer.XForms"
             xmlns:pdfviewer="clr-namespace:Syncfusion.SfPdfViewer.XForms;assembly=Syncfusion.SfPdfViewer.XForms"
             xmlns:listView="clr-namespace:Syncfusion.ListView.XForms;assembly=Syncfusion.SfListView.XForms"
             x:Class="AnnotationsListView.MainPage">
 
 <ContentPage.BindingContext>
  <local:AnnotationsListViewModel x:Name="viewmodel"></local:AnnotationsListViewModel>
 </ContentPage.BindingContext>
 
 <ContentPage.Resources>
  <ResourceDictionary>
   <local:ImageSourceConverter x:Key="ImageSourceConverter"/>
  </ResourceDictionary>
 </ContentPage.Resources>
 
 <navigationdrawer:SfNavigationDrawer x:Name="navigationDrawer" DrawerFooterHeight="0" DrawerHeaderHeight="50">
  <navigationdrawer:SfNavigationDrawer.ContentView>
   <Grid x:Name="mainContentView" BackgroundColor="White">
    <Grid.RowDefinitions>
     <RowDefinition Height="auto"/>
     <RowDefinition/>
    </Grid.RowDefinitions>
    <StackLayout BackgroundColor="#1aa1d6" Orientation="Horizontal">
      <Button x:Name="hamburgerButton" HeightRequest="50" WidthRequest="50"
                HorizontalOptions="Center" FontSize="14"
                BackgroundColor="#1aa1d6"
                Clicked="hamburgerButton_Clicked"
                Margin="5,0,0,0"/>
     <Label x:Name="headerLabel" HeightRequest="50"  HorizontalTextAlignment="Center" VerticalTextAlignment="Center" Text="Annotaions ListView" FontSize="20" TextColor="White" BackgroundColor="#1aa1d6"/>
   </StackLayout>
   <pdfviewer:SfPdfViewer x:Name="pdfViewer" Grid.Row="1" InputFileStream="{Binding PdfDocumentStream}"></pdfviewer:SfPdfViewer>
   </Grid>
  </navigationdrawer:SfNavigationDrawer.ContentView>
  <navigationdrawer:SfNavigationDrawer.DrawerHeaderView>
   <Grid BackgroundColor="#1aa1d6">
    <StackLayout Orientation="Horizontal" HorizontalOptions="Start"
                 VerticalOptions="Center" >
      <Label Text="Annotations" FontSize="20" TextColor="White" Margin="10,0,0,0"/>
      <Label Text="(" FontSize="20" TextColor="White" Margin="5,0,0,0"/>
      <Label BindingContext="{x:Reference Name=pdfViewer}" Text="{Binding Annotations.Count}" TextColor="White" FontSize="20"/>
      <Label Text=")" FontSize="20" TextColor="White"/>
    </StackLayout>
   </Grid>
  </navigationdrawer:SfNavigationDrawer.DrawerHeaderView>
  <navigationdrawer:SfNavigationDrawer.DrawerContentView>
    <listView:SfListView BackgroundColor="White" x:Name="listView" AllowGroupExpandCollapse="True"
                         ItemTapped="listView_ItemTapped"
                         BindingContext="{x:Reference Name=pdfViewer}"
                         ItemsSource="{Binding Annotations}">
      <listView:SfListView.GroupHeaderTemplate>
        <DataTemplate>
         <Grid BackgroundColor="#E4E4E4">
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
          </Grid.ColumnDefinitions>
          <StackLayout Orientation="Horizontal" HorizontalOptions="Start"
                       VerticalOptions="Center" >
            <Label Text="{Binding Key}" TextColor="Black" FontSize="Medium" Margin="10,0,0,0"/>
          </StackLayout>
          <StackLayout Orientation="Horizontal" Grid.Column="1"
                       HorizontalOptions="EndAndExpand" VerticalOptions="Center" Margin="0,0,5,0">
           <Label Text="{Binding Count}" FontSize="Medium" TextColor="Black" />
             <Image VerticalOptions="Center" HeightRequest="15"
                    WidthRequest="15"
                    Source="{Binding IsExpand, Converter={StaticResource ImageSourceConverter}}">
             </Image>
          </StackLayout>
         </Grid>
        </DataTemplate>
      </listView:SfListView.GroupHeaderTemplate>
      <listView:SfListView.ItemTemplate>
       <DataTemplate>
        <ViewCell>
          <local:ListViewItem />
        </ViewCell>
       </DataTemplate>
     </listView:SfListView.ItemTemplate>
    </listView:SfListView>
   </navigationdrawer:SfNavigationDrawer.DrawerContentView>
  </navigationdrawer:SfNavigationDrawer>
</ContentPage>

In the following code example, the ImageSourceConverter class changes the expand and collapse images displayed in the list view’s page grouped header.

public class ImageSourceConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
    if ((bool)value)
     return ImageSource.FromResource("AnnotationsListView.Assets.Expand.png");
    else
     return ImageSource.FromResource("AnnotationsListView.Assets.Collapse.png");
  }
 
  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  {
    throw new NotImplementedException();
  }
}

Implement navigation on annotation selection

Next, select an annotation that will navigate you to its corresponding position in the PDF. This is done by passing the required annotation data as a parameter to the PDF Viewer component’s SelectAnnotation method and setting the VerticalOffset property with the selected annotation’s y-position concerning the scroll point.

Implement the following code logic to navigate to the selected annotation in the listView_ItemTapped event handler of the MainPage partial class in the MainPage.xaml.cs file.

private void listView_ItemTapped(object sender, Syncfusion.ListView.XForms.ItemTappedEventArgs e)
{
  double x = 0;
  double y = 0;
 
  if (e.ItemType != Syncfusion.ListView.XForms.ItemType.GroupHeader)
  {
    pdfViewer.AnnotationMode = AnnotationMode.None;
 
    IAnnotation annotation = e.ItemData as IAnnotation;
    pdfViewer.SelectAnnotation(annotation);
 
    if (annotation is ShapeAnnotation shape)
    {
      x = shape.Bounds.X;
      y = shape.Bounds.Y;
    }
    else if (annotation is TextMarkupAnnotation textMarkup)
    {
      x = textMarkup.Bounds[0].X;
      y = textMarkup.Bounds[0].Y;
    }
    else if (annotation is FreeTextAnnotation freeText)
    {
      x = freeText.Bounds.X;
      y = freeText.Bounds.Y;
    }
    else if (annotation is InkAnnotation ink)
    {
      x = ink.Bounds.X;
      y = ink.Bounds.Y;
    }
 
    var points = pdfViewer.ConvertPagePointToScrollPoint(new Point(x, y), annotation.PageNumber);
    pdfViewer.VerticalOffset = (float)points.Y - 30;
 
    navigationDrawer.ToggleDrawer();
  }
}

GitHub reference

Check out the example to view PDF annotations as a list and navigate to them using Syncfusion Xamarin.Forms PDF Viewer component. Execution of this example app will provide output like in the following GIF image.

View PDF Annotations as a List and Navigate to Them Using Xamarin.Forms PDF Viewer

Achieve more

You can add more functionalities, like removing specific and all annotations, locking, exporting, and importing annotations into your app. To learn more about the functionalities supported in the Xamarin PDF Viewer component, refer to the getting started documentation.

Conclusion

Thanks for reading! I hope you have a clear idea of how to view annotations as a list and navigate to them using Syncfusion’s Xamarin.Forms PDF Viewer component. Try this in your app and share your feedback in the comment section below!

If you aren’t a customer, you can try our 30-day free trial to check out these features. Also, try our other Xamarin examples from this GitHub location.

You can contact us through our support forum, support portal, or feedback portal. We are always happy to assist you!

Related blogs

Tags:

Share this post:

Popular Now

Be the first to get updates

Subscribe RSS feed

Be the first to get updates

Subscribe RSS feed