Step-by-Step Guide: Downloading PDFs from SharePoint and Displaying Them in a Xamarin App
Tags: mobile, pdf, xamarin, desktop
Published: 2023-01-24 12:28:14

---
title: Step-by-Step Guide: Downloading PDFs from SharePoint and Displaying Them in a Xamarin App
published: true
date: 2023-01-24 11:56:27 UTC
tags: mobile, pdf, xamarin, desktop
canonical_url: https://www.syncfusion.com/blogs/post/step-by-step-guide-downloading-pdfs-from-sharepoint-and-displaying-them-in-a-xamarin-app.aspx
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yrsxle02jcvclp3vw6u0.png
---
As we all know, [Microsoft SharePoint](https://www.microsoft.com/en-in/microsoft-365/sharepoint/collaboration "Microsoft SharePoint") is one of the most popular and widely used applications for storing files in the cloud. In this blog, we will see how to implement SharePoint authentication, access PDF files, and view them easily in a Xamarin application using our [Syncfusion Xamarin PDF Viewer](https://www.syncfusion.com/xamarin-ui-controls/xamarin-pdf-viewer "Syncfusion Xamarin PDF Viewer").

Let’s get started!

## Configuring the Xamarin application using the Azure Portal

To start with, you need to register your Xamarin application in Azure AD. Sign into the [Azure Portal](https://portal.azure.com/ "Azure Portal"), search for and select **Azure Active Directory** , then go to the **App registrations** tab and select **New registration**.

**Step 1:** In the **Register an application** page:

1. Enter a **Name** for your app registration.
2. Select the type of accounts you want to grant access to your app.
3. Select **Register**. ![Register an application window](https://www.syncfusion.com/blogs/wp-content/uploads/2023/01/Register-an-application-window.png)

**Step 2:** After the app registration is created, take note of the **Application (client) ID** for later use. You can find it in the **Overview** tab of the application registration we just created.

 ![Note down the Application (client) ID](https://www.syncfusion.com/blogs/wp-content/uploads/2023/01/Note-down-the-Application-client-ID.png)

**Step 3:** Then, go to the **Authentication** tab, click **Add a platform** , and add both iOS and Android. Just for Android, we need to generate and provide a signature hash.

 ![Go to the Authentication tab, click Add a platform, and add both iOS and Android](https://www.syncfusion.com/blogs/wp-content/uploads/2023/01/Go-to-the-Authentication-tab-click-Add-a-platform-and-add-both-iOS-and-Android.png)
## Creating and configuring a Xamarin application

Now, integrate the Microsoft SharePoint authentication into our Xamarin application to access the PDF documents and view them using our Syncfusion Xamarin PDF Viewer.

**Step 1:** [Create a new Xamarin.Forms project](https://learn.microsoft.com/en-us/xamarin/get-started/first-app/ "Build your first Xamarin.Forms app documentation").

**Step 2:** Install the following NuGet packages in the PCL and all platform projects:

- [**PnP.Framework**](https://www.nuget.org/packages/PnP.Framework/ "PnP.Framework NuGet package")—To authenticate and retrieve data from SharePoint.
- [**Syncfusion.Xamarin.SfPdfViewer**](https://www.nuget.org/packages/Syncfusion.Xamarin.SfPdfViewer "Syncfusion.Xamarin.SfPdfViewer NuGet package")—To view the PDF documents.
- [**Syncfusion.Xamarin.SfTreeView**](https://www.nuget.org/packages/Syncfusion.Xamarin.SfTreeView "Syncfusion.Xamarin.SfTreeView NuGet package") —To visualize the retrieved SharePoint documents like in a file explorer.
- [**Syncfusion.Xamarin.SfProgressBar**](https://www.nuget.org/packages/Syncfusion.Xamarin.SfProgressBar "Syncfusion.Xamarin.SfProgressBar NuGet package")—To indicate the progress of a task.

Additionally, in iOS, to launch the application with Syncfusion controls, you need to call the **SfPdfDocumentViewRenderer.Init()**,**SfTreeViewRenderer.Init()**, and **SfLinearProgressBarRenderer.Init()** methods in the **FinishedLaunching** overridden method of the **AppDelegate** class after the Xamarin.Forms framework has been initialized and before the **LoadApplication** is called. Refer to the following code sample.

```csharp
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    global::Xamarin.Forms.Forms.Init();
    Syncfusion.SfPdfViewer.XForms.iOS.SfPdfDocumentViewRenderer.Init();
    Syncfusion.XForms.iOS.TreeView.SfTreeViewRenderer.Init();
    Syncfusion.XForms.iOS.ProgressBar.SfLinearProgressBarRenderer.Init();
    LoadApplication(new App());
    App.ParentWindow = null;
    return base.FinishedLaunching(app, options);
}
```

**Note:** Here, the **SfTreeView** and **SfProgressBar** have just been used to improve the usability of the application. You can replace these with the controls of your choice.

**Step 3:** Create model classes named **FileManager** and **PDFFile** to hold the data of the SharePoint documents and the PDF document, respectively. Refer to the following code example.

**FileManager.cs**

```csharp
using System.ComponentModel;
using Xamarin.Forms;
using Microsoft.SharePoint.Client;

namespace SharePoint
{
    public class FileManager : INotifyPropertyChanged
    {
        private string itemName;
        private bool hasChildNodes;
        private Folder folder;
        private File file;
        private ImageSource imageIcon;
        
        public FileManager()
        {
        }
        
        public string ItemName
        {
            get { return itemName; }
            set
            {
                itemName = value;
                RaisedOnPropertyChanged("ItemName");
            }
        }
        
        public bool HasChildNodes
        {
            get { return hasChildNodes; }
            set
            {
                hasChildNodes = value;
                RaisedOnPropertyChanged("HasChildNodes");
            }
        }
        
        public Folder Folder
        {
            get { return folder; }
            set
            {
                folder = value;
                RaisedOnPropertyChanged("Folder");
            }
        }
        
        public File File
        {
            get { return file; }
            set
            {
                file = value;
                RaisedOnPropertyChanged("File");
            }
        }
       
        public ImageSource ImageIcon
        {
            get { return imageIcon; }
            set
            {
                imageIcon = value;
                RaisedOnPropertyChanged("ImageIcon");
            }
        }
        
        public event PropertyChangedEventHandler PropertyChanged;
        
        public void RaisedOnPropertyChanged(string _PropertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(_PropertyName));
            }
        }
    }
}
```

**PDFFile.cs**

```csharp
using System.IO;

namespace SharePoint
{
    public class PdfFile
    {
        public Stream DocumentStream { get; set; }
        public string Name { get; set; }
        public PdfFile(Stream pdfStream,string pdfName)
        {
            DocumentStream = pdfStream;
            Name = pdfName;
        }
    }
}
```

**Step 4:** Create a **ViewModel** class named **SharePointViewModel.cs**. Implement the logic to authenticate and retrieve the SharePoint documents and return the document stream of the selected PDF file in the File Manager. Refer to the following code example.

**SharePointViewModel.cs**

```csharp
using Microsoft.Identity.Client;
using Microsoft.SharePoint.Client;
using PnP.Framework;
using Syncfusion.TreeView.Engine;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace SharePoint
{
    internal class SharePointViewModel
    {
        // Replace with your SharePoint tenant name.
        private const string Tenant = "{YOUR TENANT NAME}";
        
        // Replace with your targeted SharePoint site name.
        private const string SiteName = "{YOUR SITE NAME}";
        
        // Replace with your Azure AD Application's Client ID.
        private const string ClientId = "{YOUR CLIENT ID}";
        
        // Replace with your Azure AD Application's Package Name or Bundle ID.
        private const string AppId = "{YOUR APP ID}";
        
        // For Android, replace with your Authentication Signature Hash.
        private const string SignatureHash = "{YOUR SIGNATURE HASH}";
        
        public ObservableCollection<FileManager> Documents { get; set; }        
        public ClientContext Context { get; set; }        
        public ICommand DocumentsViewOnDemandCommand { get; set; }
        public SharePointViewModel()
        {
            DocumentsViewOnDemandCommand = new Command(ExecuteOnDemandLoading, CanExecuteOnDemandLoading);
        }
        
        private bool CanExecuteOnDemandLoading(object sender)
        {
            var hasChildNodes = ((sender as TreeViewNode).Content as FileManager).HasChildNodes;
            if (hasChildNodes)
                return true;
            else
                return false;
        }
        
        private void ExecuteOnDemandLoading(object obj)
        {
            var node = obj as TreeViewNode;
            
            // Skip the repeated population of child items when every time the node expands.
            if (node.ChildNodes.Count > 0)
            {
                node.IsExpanded = true;
                return;
            }
            
            //Animation starts for expander to show progress of load on demand.
            node.ShowExpanderAnimation = true;
            
            Microsoft.SharePoint.Client.Folder root = (node.Content as FileManager).Folder;
            
            var documents = GetDocuments(root);
            
            node.PopulateChildNodes(documents);
            
            if (documents.Count > 0)
            {
                //Expand the node after child items are added.              
                node.IsExpanded = true;
            }
           
            //Stop the animation after load on demand is executed. If animation not stopped, it remains still after execution of load on demand.
            node.ShowExpanderAnimation = false;
        }
        
        /// <summary>
        /// Perform SharePoint authentication and return the documents of the target site.
        /// </summary>
        /// <returns>Documents of the target site</returns>
        internal async Task AuthenticateAndAcquireDocuments()
        {
            string redirectURI = DeviceInfo.Platform == DevicePlatform.Android ?
                $"msauth://{AppId}/{SignatureHash}" : $"msauth.{AppId}://auth";
            
            IPublicClientApplication PublicClientApp = PublicClientApplicationBuilder.Create(ClientId)
                .WithIosKeychainSecurityGroup(AppId)
                .WithRedirectUri(redirectURI)
                .WithAuthority("https://login.microsoftonline.com/common")
                .Build();
            
            var _scopes = new String[] { $"https://{Tenant}.sharepoint.com/AllSites.Read" }; //Replace with your own permissions.
            
            try
            {
                AuthenticationResult authResult = await PublicClientApp.AcquireTokenInteractive(_scopes)
                    .WithParentActivityOrWindow(App.ParentWindow)
                    .WithUseEmbeddedWebView(true)
                    .ExecuteAsync();
                
                var authManager = new AuthenticationManager().GetAccessTokenContext( $"https://{Tenant}.sharepoint.com/sites/{SiteName}",
                    authResult.AccessToken);
                
                Context = authManager.GetSiteCollectionContext();
                
                var web = Context.Web;//Gets target site web details.
                var docs = web.Lists.GetByTitle("Documents");//Gets site's documents list.
                Var root = docs.RootFolder; //Root folder.
                Documents = GetDocuments(root);
            }
            catch (Exception e)
            {
            }
        }
        
         /// <summary>
        /// Returns the documents present in the passed root or parent folder.
        /// </summary>
        /// <param name="root">Root folder</param>
        /// <returns>Documents of the root or parent folder</returns>
        internal ObservableCollection<FileManager> GetDocuments(Microsoft.SharePoint.Client.Folder root)
        {
            ObservableCollection<FileManager> documents = new ObservableCollection<FileManager>();
            
            Assembly assembly = typeof(DocumentsPage).GetTypeInfo().Assembly;
            Context.Load(root, f => f.ItemCount, f => f.Folders);
            Context.Load(root, f => f.ItemCount, f => f.Files);
            Context.ExecuteQuery();
            
            foreach (Microsoft.SharePoint.Client.Folder folder in root.Folders)
            {
                bool hasChildNodes = folder.ItemCount > 0 ? true : false;
                var folderItem = new FileManager()
                {
                    ItemName = folder.Name,
                    Folder = folder,
                    HasChildNodes = hasChildNodes,
                    ImageIcon = ImageSource.FromResource("SharePoint.Icons.treeview_folder.png", assembly)
                };
                documents.Add(folderItem);
            }
            
            foreach (Microsoft.SharePoint.Client.File file in root.Files)
            {
                if (file.Name.EndsWith(".pdf"))
                {
                    var fileItem = new FileManager()
                    {
                        ItemName = file.Name,
                        File = file,
                        ImageIcon = ImageSource.FromResource("SharePoint.Icons.treeview_pdf.png", assembly)
                    };
                    documents.Add(fileItem);
                }
            }
            return documents;
        }
        
        /// <summary>
        /// Returns the chosen PDF document details.
        /// </summary>
        /// <param name="file">PDF file chosen from the File Explorer</param>
        /// <returns>PDF document details</returns>
        internal PdfFile GetPdfDocumentDetails(Microsoft.SharePoint.Client.File file)
        {
            MemoryStream PdfDocumentStream = new MemoryStream();
            var fileStream = file.OpenBinaryStream();
            Context.Load(file);
            Context.ExecuteQuery();
            fileStream.Value.CopyTo(PdfDocumentStream);
            PdfDocumentStream.Position = 0;
            return new PdfFile(PdfDocumentStream, file.Name);
        }
    }
}
```

Make sure to replace the following things in the previous code example:

- **Tenant** —SharePoint tenant name.
- **SiteName** —SharePoint site name.
- **ClientId** —Application’s Client ID noted from the Azure AD.
- **AppId** —Application’s package name [Android] or bundle ID [iOS] given during Azure AD authentication.
- **SignatureHash** —Signature hash noted from Android’s authentication.

**Step 5:** Create a view named **PdfViewerPage** to view the selected PDF file from the SharePoint documents. Refer to the following code example.

**PdfViewerPage.xaml**

```xml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:syncfusion="clr-namespace:Syncfusion.SfPdfViewer.XForms;assembly=Syncfusion.SfPdfViewer.XForms" 
             x:Class="SharePoint.PdfViewerPage">
    <ContentPage.Content>
        <syncfusion:SfPdfViewer x:Name="PdfViewer"/>
    </ContentPage.Content>
</ContentPage>
```

**PdfViewerPage.xaml.cs**

```csharp
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace SharePoint
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class PdfViewerPage : ContentPage
    {
        public PdfViewerPage(PdfFile pdfFile)
        {
            InitializeComponent();
            this.Title = pdfFile.Name;
            pdfFile.DocumentStream.Position = 0;
            PdfViewer.LoadDocument(pdfFile.DocumentStream);
        }
        
        protected override void OnDisappearing()
        {
            PdfViewer.Dispose();
            base.OnDisappearing();
        }
    }
}
```

**Step 6:** Create another view named **DocumentsPage** to login and display the SharePoint documents of the given site name in the File Explorer-like Treeview. Also, in the TreeView’s **ItemTapped** handler method, implement the logic to retrieve the selected PDF document details and navigate to the PdfViewerPage to view them.

**Note:** In this example, we have used TreeView’s [ItemTemplate Selector](https://help.syncfusion.com/xamarin/treeview/appearance#itemtemplate-selector "ItemTemplate Selector in Xamarin PDF Viewer") to customize the appearance of each item with different templates to create the file explorer view.

Refer to the following code example.

**DocumentsPage.xaml**

```xml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:treeView="clr-namespace:Syncfusion.XForms.TreeView;assembly=Syncfusion.SfTreeView.XForms"
             xmlns:progressBar="clr-namespace:Syncfusion.XForms.ProgressBar;assembly=Syncfusion.SfProgressBar.XForms"
             xmlns:local="clr-namespace:SharePoint"
             NavigationPage.HasNavigationBar="False"
             x:Class="SharePoint.DocumentsPage">
    
    <ContentPage.BindingContext>
        <local:SharePointViewModel/>
    </ContentPage.BindingContext>
    
    <ContentPage.Resources>
        <ResourceDictionary>
            <local:ItemTemplateSelector x:Key="ItemTemplateSelector" />
        </ResourceDictionary>
    </ContentPage.Resources>
    
    <ContentPage.Content>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <progressBar:SfLinearProgressBar x:Name="ProgressBar" Grid.Row="0" HeightRequest="5" IsIndeterminate="True" IsVisible="false" ProgressColor="#038387"/>
            <StackLayout Grid.Row="1" Orientation="Vertical" VerticalOptions="Center">
                <Image x:Name="SharepointImage" HeightRequest="175" WidthRequest="175" VerticalOptions="Center"></Image>
                <Button Text="SHAREPOINT LOGIN" x:Name="LoginButton" WidthRequest="250"
                        HorizontalOptions="Center"
                        Font="18"
                        Clicked="LoginButton_Clicked"/>
                <Label x:Name="DocumentsTitleLabel" HeightRequest="50" IsVisible="false" Text="Documents" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" FontSize="20" TextColor="White" BackgroundColor="#038387"/>
                <treeView:SfTreeView x:Name="DocumentsView" ItemHeight="40"
                                     IsVisible="false"
                                     ChildPropertyName="SubFiles"
                                     LoadOnDemandCommand="{Binding DocumentsViewOnDemandCommand}"
                                     ItemTemplateContextType="Node"                                   
                                     ItemTapped="DocumentsView_ItemTapped"
                                     SelectionBackgroundColor="#038387"
                                     SelectionForegroundColor="White"
                                     Indentation="20" 
                                     ExpanderWidth="40" ItemTemplate="{StaticResource ItemTemplateSelector}">
                </treeView:SfTreeView>
            </StackLayout>
        </Grid>
    </ContentPage.Content>
</ContentPage>
```

**DocumentsPage.xaml.cs**

```csharp
using System;
using System.Reflection;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace SharePoint
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class DocumentsPage : ContentPage
    {
        public DocumentsPage()
        {
            InitializeComponent();
            SharepointImage.Source = ImageSource.FromResource("SharePoint.Icons.sharepoint.png",
                typeof(DocumentsPage).GetTypeInfo().Assembly);
        }
        
        private async void LoginButton_Clicked(object sender, EventArgs e)
        {
            ProgressBar.IsVisible = true;
            LoginButton.IsVisible = false;
            
            await (BindingContext as SharePointViewModel).AuthenticateAndAcquireDocuments();
            
            SharepointImage.IsVisible = false;
            DocumentsTitleLabel.IsVisible = true;
            DocumentsView.IsVisible = true;
            DocumentsView.ItemsSource = (BindingContext as SharePointViewModel).Documents;
            ProgressBar.IsVisible = false;
        }
        
        private void DocumentsView_ItemTapped(object sender, Syncfusion.XForms.TreeView.ItemTappedEventArgs e)
        {
            Microsoft.SharePoint.Client.File file = (e.Node.Content as FileManager).File;
            if (file != null)
            {
                Navigation.PushAsync(new PdfViewerPage((BindingContext as SharePointViewModel)
                    .GetPdfDocumentDetails(file)));
            }
        }
    }
}
```

In this example, you can navigate back to the **Documents** page from PDF Viewer page to choose or load another PDF document by clicking the back icon in the navigation bar. Refer to the following image.

 ![Select the back icon in the navigation bar](https://www.syncfusion.com/blogs/wp-content/uploads/2023/01/Select-the-back-icon-in-the-navigation-bar.png)

**Step 7:** Before running the application, there are some configurations that need to be done in both Android and iOS platforms to make the SharePoint authentication successful and to continue with our application.

### iOS

In iOS, to reopen our application after the authentication flow is completed, override the **OpenUrl** method in the **AppDelegate** class. Refer to the following code example.

```csharp
public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{                  
 AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(url);
 return true;
}
```

Next, open the **Entitlements.plist** file and check the **Enable Keychain** option. This will add an entry for our app to the keychain, which is where iOS securely stores our credentials.

 ![Select the Keychain checkbox](https://www.syncfusion.com/blogs/wp-content/uploads/2023/01/Select-Keychain-checkbox.png)

To allow the application to use the keychain, set the **Custom Entitlements** setting to point to the **Entitlements.plist** file. This setting option can be found in the **Properties -> iOS Bundle Signing -> Additional Resources**.

 ![Navigate to Properties , iOS Bundle Signing and then Additional Resources](https://www.syncfusion.com/blogs/wp-content/uploads/2023/01/Navigate-to-Properties-iOS-Bundle-Signing-and-then-Additional-Resources.png)

Finally, configure the iOS application to respond to the callback URL by defining a URL type in the **Info.plist** file. Add or update the **Identifier** , **URL Schemes,** and **Role** properties in the URL type. Refer to the following screenshot.

 ![Add or update the Identifier, URL Schemes, and Role properties in the URL type](https://www.syncfusion.com/blogs/wp-content/uploads/2023/01/Add-or-update-the-Identifier-URL-Schemes-and-Role-properties-in-the-URL-type.png)
### Android

In Android, to reopen our application after the authentication is completed, override the **OnActivityResult** method in the **MainActivity** class. Refer to the following code example.

```csharp
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
 base.OnActivityResult(requestCode, resultCode, data);   
 AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data);
}
```

Next, configure the Android application to respond to the callback URL by providing an **activity** and an **intent-filter** in the **AndroidManifest.xml** file. Refer to the following code example.

**AndroidManifest.xml**

```xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.SharePoint" android:installLocation="preferExternal">
  <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" />
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  
  <application android:label="SharePoint.Android">
    
    <activity android:name="microsoft.identity.client.BrowserTabActivity">
      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="msauth" android:host="com.syncfusion.sharepointauth" android:path="{YOUR_SIGNATURE_HASH}" />
      </intent-filter>
    </activity>
  
  </application>
</manifest>
```

**Note:** Please make sure to replace the text {YOUR\_SIGNATURE\_HASH} with your application’s signature hash in the AndroidManifest.xml file.

**Step 8:** Finally, you can deploy the application. The output of this example application will look as follows.

 ![Downloading PDFs from SharePoint and Displaying Them using Xamarin.Forms PDF Viewer](https://www.syncfusion.com/blogs/wp-content/uploads/2023/01/Downloading-PDFs-from-SharePoint-and-Displaying-Them-using-Xamarin.Forms-PDF-Viewer.gif)
## Resource

For more details, check out the complete code example [on GitHub](https://github.com/SyncfusionExamples/load-and-view-pdf-files-from-sharepoint-in-xamarin "Load and View PDF files from SharePoint using Syncfusion Xamarin PDF Viewer GitHub demo").

## Conclusion

Thanks for reading! We have seen in this blog how to access PDF files from SharePoint and load them using Syncfusion’s [Xamarin.Forms PDF Viewer](https://www.syncfusion.com/xamarin-ui-controls/xamarin-pdf-viewer "Xamarin PDF Viewer") control. Try this in your application and share your feedback in the comment section below!

If you aren’t a customer, you can try our 30-day [free trial](https://www.syncfusion.com/downloads "Free evaluation of the Syncfusion Essential Studio") to check out these features. Also, try our other Xamarin examples from this [GitHub](https://github.com/syncfusion/xamarin-demos "Syncfusion Xamarin examples on GitHub") location.

If you have any questions, you can contact us through our [support forum](https://www.syncfusion.com/forums "Syncfusion Support Forum"), [support portal](https://support.syncfusion.com/ "Syncfusion Support Portal"), or [feedback portal](https://www.syncfusion.com/feedback/ "Syncfusion Feedback Portal"). We are always happy to assist you!

## Related blogs

- [Easily Lock and Unlock Annotations Using Xamarin.Forms PDF Viewer](https://www.syncfusion.com/blogs/post/lock-and-unlock-annotations-using-xamarin-forms-pdf-viewer.aspx "Blog: Easily Lock and Unlock Annotations Using Xamarin.Forms PDF Viewer")
- [Migrating Syncfusion Xamarin.Forms Controls to .NET MAUI](https://www.syncfusion.com/blogs/post/migrating-syncfusion-xamarin-forms-controls-to-net-maui.aspx "Blog: Migrating Syncfusion Xamarin.Forms Controls to .NET MAUI")
- [View PDF Annotations as a List and Navigate Using Xamarin.Forms PDF Viewer](https://www.syncfusion.com/blogs/post/view-pdf-annotations-as-a-list-and-navigate-using-xamarin-forms-pdf-viewer.aspx "Blog: View PDF Annotations as a List and Navigate Using Xamarin.Forms PDF Viewer")
- [Lazy Load JSON Data in Xamarin.Forms ListView: An Overview](https://www.syncfusion.com/blogs/post/lazy-load-json-data-in-xamarin-forms-listview-an-overview.aspx "Blog: Lazy Load JSON Data in Xamarin.Forms ListView: An Overview")