How to Auto-Save PDF Annotations and Forms in .NET MAUI Using PDF Viewer

syncfusionsyncfusion
14 min read

TL;DR: Auto-saving PDF edits in .NET MAUI apps prevents data loss and improves user experience. This guide shows how to use Syncfusion® PDF Viewer to implement real-time auto-save for annotations and form fields using MVVM and async programming.

Modern PDF editing apps must protect user data without disrupting the workflow. Users expect their PDF annotations and form entries to be saved automatically, especially in mobile and desktop applications built with .NET MAUI. Losing unsaved edits can lead to frustration and poor user experience.

With Syncfusion® PDF Viewer for .NET MAUI, developers can implement a robust auto-save mechanism for PDF annotations and form fields, ensuring that every change is preserved in real-time. This guide walks you through building an auto-save workflow using MVVM and asynchronous programming, helping you deliver a seamless, cross-platform PDF editing experience.

Why auto-save matters in PDF editing

Auto-save is an automated document preservation system that monitors user interactions and triggers save operations based on predefined conditions. Unlike traditional saving mechanisms that require explicit user action, auto-saving works transparently in the background. It acts as a safeguard against real-world disruptions that can cause data loss.

Scenarios where auto-save occurred

  • Incoming calls that suspend the app

  • Battery depletion or unexpected shutdowns

  • System memory management is terminating the app.

  • Crashes during editing sessions

  • Accidental app closures

How Auto-Save works in a PDF Viewer

Implementing auto-save in a PDF viewer involves more than simply saving at regular intervals. A robust system includes:

  • Real-time monitoring of document modifications ( annotations, form fields, markups )

  • Intelligent triggering based on editing events rather than fixed time intervals.

  • Background processing using asynchronous operations to prevent UI blocking.

  • Full document persistence: the entire PDF is rewritten with all changes.

Prerequisites

Building a reliable auto‑save feature for PDF applications requires the right mix of frameworks, components, and design patterns. Here’s the stack that makes it possible:

  1. .NET MAUI: Microsoft’s cross-platform UI framework

  2. Syncfusion® PDF Viewer : A rich component for viewing and editing PDFs. To begin working with Syncfusion’s PDF Viewer for .NET MAUI, refer to this official documentation.

  3. MVVM architecture: Ensures clean separation of UI and business logic.

  4. XAML data binding: Dynamic UI updates

  5. C# Async programming: Non-blocking operations for file I/O.

Steps to implement Auto-Save in .NET MAUI PDF Viewer

Local Device Storage

Follow these key steps to implement local device auto-save functionality for PDF edits in a .NET MAUI app using Syncfusion® PDF Viewer.

Step 1: Design the PDF editing interface

Begin by designing the user interface in XAML. Create a layout that includes:

  1. A toolbar with buttons for opening and saving PDF files.

  2. A toggle control for enabling or disabling auto-save.

  3. A label to display status messages.

Below the toolbar, place the Syncfusion® PDF Viewer control to render and interact with the document.

XAML:

<!-- Main layout container with two rows: toolbar and PDF viewer -->
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" /> <!-- Toolbar row - auto-sized -->
        <RowDefinition Height="*" /> <!-- PDF viewer row - fills remaining space -->
    </Grid.RowDefinitions>
    <!-- Top toolbar containing file operations and status notifications -->
    <Border Grid.Row="0">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" /> <!-- Notification area - takes remaining space -->
                <ColumnDefinition Width="Auto" /> <!-- Button area - auto-sized -->
            </Grid.ColumnDefinitions>
            <!-- Status notification display showing current operation or file state -->
            <Label Grid.Column="0"
                   x:Name="NotificationLabel"
                   Text="{Binding NotificationText}"/>
            <!-- Horizontal container for toolbar buttons and controls -->
            <HorizontalStackLayout Grid.Column="1">
                <!-- File open button - uses Material Design folder icon -->
                <Button x:Name="OpenButton"
                        ToolTipProperties.Text="Open PDF file"
                        Command="{Binding OpenPdfCommand}" />
                <!-- Manual save button - enabled only when auto-save is disabled -->
                <Button x:Name="SaveButton"
                        ToolTipProperties.Text="Save PDF file manually""
                        Command="{Binding SavePdfCommand}" IsEnabled="{Binding IsAutoSaveEnabled, Converter={StaticResource InverseBooleanConverter}}"/>
                <!-- Auto-save toggle control with checkbox and label -->
                <Border StrokeThickness="1">
                    <StackLayout Orientation="Horizontal" VerticalOptions="Center">
                        <!-- Checkbox bound to auto-save enabled property -->
                        <CheckBox IsChecked="{Binding IsAutoSaveEnabled}" VerticalOptions="Center" />
                        <Label Text="Auto Save" VerticalOptions="Center" />
                    </StackLayout>
                </Border>
            </HorizontalStackLayout>
        </Grid>
    </Border>
    <!-- Syncfusion PDF Viewer control with event handlers for document editing -->
    <pdfViewer:SfPdfViewer Grid.Row="1"
                           x:Name="PdfViewer"/>
</Grid>

Step 2: Open a PDF file

To begin working with a PDF document, integrate a platform-specific file picker that allows users to browse and select a file from their device. Once selected, load the file into the Syncfusion® PDF Viewer using a stream so it is ready for interaction and modification.

C#:

/// <summary>
/// Opens a PDF file using the platform file picker.
/// Configures platform-specific file types and loads the selected PDF into the viewer.
/// </summary>
private async void OpenPdf()
{
    // Define platform-specific PDF file types for the file picker
    var customFileType = new FilePickerFileType(
    new Dictionary<DevicePlatform, IEnumerable<string>>
    {
        { DevicePlatform.Android, new[] { "application/pdf" } },
        { DevicePlatform.iOS, new[] { "com.adobe.pdf" } },
        { DevicePlatform.WinUI, new[] { ".pdf" } },
        { DevicePlatform.MacCatalyst, new[] { "pdf" } },
    });
    // Configure file picker options
    var options = new PickOptions()
    {
        PickerTitle = "Please select a PDF file",
        FileTypes = customFileType,
    };
    // Show file picker and get user selection
    var result = await FilePicker.Default.PickAsync(options);
    if (result != null)
    {
        // Open the selected file as a stream and load it into the PDF viewer
        var stream = await result.OpenReadAsync();
        if (PdfViewer != null)
        {
            PdfViewer.DocumentSource = stream;
        }
    }
}

Step 3: Store the file path

After loading the PDF, store its file path and name in the ViewModel. This information is essential for saving changes back to the original location. Maintaining access to the file path allows overwrite operations during auto‑save and ensures that edits are consistently preserved in the correct document.

// Show file picker and get user selection
var result = await FilePicker.Default.PickAsync(options);
if (result != null)
{
    // Open the selected file as a stream and load it into the PDF viewer
    var stream = await result.OpenReadAsync();
    if (PdfViewer != null)
    {
        _currentFilePath = result.FullPath;
        _currentFileName = result.FileName;
    }
}

Step 4: Monitor document changes via events

To implement auto-saving effectively, you need a reliable way to detect when the PDF document has been modified. The Syncfusion® PDF Viewer offers built-in events designed for this purpose. By subscribing to these events, you can monitor user interactions and trigger save operations only when necessary, ensuring that changes are captured in real time without redundant saves.

Focus on the following key events:

  1. AnnotationAdded: Raised when a new annotation (such as a highlight, shape, or comment ) is added to the document.

  2. AnnotationRemoved: Triggered when an existing annotation is deleted.

  3. AnnotationEdited: Fired when a user modifies an existing annotation, such as resizing or changing its properties.

  4. FormFieldValueChanged: Triggered when the value of a form field (e.g., text box, checkbox ) is changed.

Each of these events represents a meaningful edit to the document. By handling them in your code-behind or ViewModel, you can initiate the auto-save logic conditionally, based on whether auto-save is enabled, ensuring that user changes are preserved without requiring manual intervention.

XAML:

<!-- Syncfusion PDF Viewer control with event handlers for document editing -->
<!-- Events are wired to track all types of PDF modifications for auto-save -->
<pdfViewer:SfPdfViewer Grid.Row="1"
                       x:Name="PdfViewer"
                       DocumentLoaded="PdfViewer_DocumentLoaded"
                       DocumentUnloaded="PdfViewer_DocumentUnloaded"
                       AnnotationAdded="PdfViewer_AnnotationAdded"
                       AnnotationRemoved="PdfViewer_AnnotationRemoved"
                       AnnotationEdited="PdfViewer_AnnotationEdited"
                       FormFieldValueChanged="PdfViewer_FormFieldValueChanged" />

Step 5: Saving PDF edits asynchronously

To keep the user interface responsive, implement the save operation using asynchronous programming. When an edit is detected, save the updated document in the background using SaveDocumentAsync functionality of the PDF Viewer. This prevents UI blocking and allows users to continue interacting with the PDF Viewer while the save process completes silently and efficiently.

C#:

/// <summary>
/// Called when the PDF document is edited (annotations added, removed, or modified).
/// Triggers auto-save if enabled, otherwise just updates the notification.
/// </summary>
public void OnDocumentEdited()
{
    if (IsAutoSaveEnabled)
    {
        // Automatically save the document when auto-save is enabled
        SavePdf();
    }
}

/// <summary>
/// Saves the current PDF document to its original file location.
/// Uses the Syncfusion PDF Viewer's SaveDocumentAsync method to preserve edits.
/// </summary>
private async void SavePdf()
{
    if (PdfViewer != null && !string.IsNullOrEmpty(_currentFilePath))
    {
        FileInfo fileInfo = new FileInfo(_currentFilePath);
        if (fileInfo.IsReadOnly == false)
        {
            // Create a memory stream to hold the saved PDF data
            using var saveStream = new MemoryStream();
            // Save the PDF document with all modifications to the memory stream
            await PdfViewer.SaveDocumentAsync(saveStream);
            // Write the saved PDF data back to the original file
            using (var fileStream = new FileStream(_currentFilePath, FileMode.Create, FileAccess.Write))
            {
                saveStream.Position = 0;
                await saveStream.CopyToAsync(fileStream);
            }
        }
    }
}

Step 6: Notify users of auto‑save progress

In an auto-save workflow, users should be kept informed about the status of their edits without disrupting their interaction with the document. Implementing a notification system allows developers to provide subtle, real-time feedback that confirms when a save operation is triggered and completed.

One way to achieve this is by exposing a bindable property in the ViewModel that reflects the current operation status. These notifications help users understand that their edits are being preserved automatically and reinforce trust in the system, especially when manual saving is not required.

MainPage.Xaml:

<!-- Status notification display showing current operation or file state -->
<Label Grid.Column="0"
       x:Name="NotificationLabel"
       Text="{Binding NotificationText}"/>

ViewModel.cs:

/// <summary>
/// Gets or sets the notification text displayed to the user.
/// Provides real-time feedback about current operations.
/// </summary>
public string NotificationText
{
    get => _notificationText;
    set
    {
        if (_notificationText != value)
        {
            _notificationText = value;
            OnPropertyChanged();
        }
    }
}

/// <summary>
/// Saves the current PDF document.
/// </summary>
private async void SavePdf()
{
    // Update notification content that save has started.
    NotificationText = "Saving - " + _currentFileName + "...";
    /// Save process will be executed here…
    // Update notification content that save is completed.
    NotificationText = _currentFileName + " - Saved";
}

Step 7: Enable or disable auto‑save with a toggle

Introduce a toggleable boolean property in the ViewModel to control whether auto-save is active. Bind this property to a checkbox in the UI, allowing users to enable or disable auto-save based on their preferences. Use this flag to conditionally execute the save logic when edits are detected, giving users control over how and when their changes are saved.

XAML:

<StackLayout Orientation="Horizontal" VerticalOptions="Center">
    <!-- Checkbox bound to auto-save enabled property -->
    <CheckBox IsChecked="{Binding IsAutoSaveEnabled}" VerticalOptions="Center" />
    <Label Text="Auto Save" VerticalOptions="Center" />
</StackLayout>

Step 8: Use built-in editing features

The Syncfusion® PDF Viewer for .NET MAUI provides built-in support for editing. Users can interactively annotate documents and fill out form fields such as text boxes, checkboxes, and combo boxes. Developers can also trigger these actions programmatically, making it easy to integrate custom toolbars or workflows.

Whether edits are made through direct interaction or custom UI elements, the viewer emits events that help detect changes and implement auto-save logic. This ensures that every meaningful update is captured and persisted automatically.

For detailed guidance on working with these features, refer to the Syncfusion® documentation:

By following these implementation steps, developers can build a responsive and reliable auto-save system that seamlessly captures user edits in real time, ensuring that every interaction with the PDF document is persistently stored without manual effort.

Below is a visual walkthrough of the auto-save feature in action. The animation demonstrates how a user opens a PDF, makes annotation edits, and sees those changes automatically saved without manual intervention.

NET MAUI PDF Viewer auto-saving annotations with toolbar

NET MAUI PDF Viewer auto-saving annotations with toolbar

Cloud storage integration

While local auto-save provides immediate protection against data loss, integrating cloud storage transforms your PDF editing application into a comprehensive document management solution. Cloud storage offers additional benefits, including cross-device synchronization, collaborative access capabilities, and unlimited scalable storage. This integration acts as a secondary layer of protection, ensuring that even if local devices fail or are lost, your PDF edits remain safely preserved and accessible from anywhere.

Let’s explore how to implement auto-save using AWS cloud services as an example. The steps are similar to the local save implementation, with additional cloud-specific steps outlined below:

Step 1: Setting up Amazon S3 storage (AWS)

Setting up Amazon S3 involves the following steps:

Create an S3 bucket

  1. Sign in to the AWS Management Console and navigate to Amazon S3 via the AWS services menu.

  2. Click Create bucket, then provide a unique name, select a region, and configure the public access settings based on your requirements.

  3. Click Create bucket to complete the process.

Configure bucket permissions

  1. Open your newly created S3 bucket and go to the Permissions

  2. Configure the Bucket Policy to control read/write access and adjust CORS settings if necessary.

Retrieve access credentials

  1. Navigate to the I AM service and create a new I AM user with programmatic access.

  2. Attach the AmazonS3FullAccess policy or customize permissions as needed.

  3. Save the Access Key ID and Secret Access Key for authentication in your application.

Step 2: Install AWS SDK dependencies in .NET MAUI App

In your .NET MAUI app, install the AWSSDK.S3 NuGet package. This enables secure interaction with Amazon S3 for opening, saving, and managing PDF files using built-in AWS APIs.

Installing AWS SDK dependencies in .NET MAUI App

Step 3: Configure AWS credentials

Create an AmazonS3Client using your credentials ( Access key and Secret key ) and region to communicate with the S3 service.

C#:

// Set your AWS credentials and region
private string accessKey = "YOUR_ACCESS_KEY";
private string secretKey = "YOUR_SECRET_KEY";
private RegionEndpoint region = RegionEndpoint.YOUR_REGION; // Change to your desired region.

// Create an Amazon S3 client using provided credentials and region.
AmazonS3Client s3Client = new AmazonS3Client(accessKey, secretKey, region);

Step 4: Open a PDF file from S3

Opening a file from AWS S3 storage involves the following steps

  1. Initiate a request to access the file using the specified bucket and key. C#:
// Specify the bucket name and object key
string bucketName = "YOUR_BUCKET_NAME";
string objectKey = "YOUR_OBJECT_KEY"; 

// Create a request to get the object (file) from the specified bucket and key.
var request = new GetObjectRequest
{
    BucketName = bucketName, // The name of the S3 bucket.
    Key = objectKey // The path or filename of the object in the bucket.
};
  1. Execute the request and retrieve the file’s metadata and data stream using GetObjectAsync method of the AmazonS3Client. C#:
// Obtain a response containing the object’s metadata and data stream.
var response = s3Client.GetObjectAsync(request).Result;
  1. Convert the object into a stream and load it into the PDF Viewer. C#:

// Access the response stream which contains the file's data.
using (var responseStream = response.ResponseStream)
{
    // Create a new memory stream to hold the file's contents.
    var memoryStream = new MemoryStream();
    // Copy the data from the response stream into the memory stream.
    responseStream.CopyTo(memoryStream);
    memoryStream.Position = 0; // Reset position before returning

    if(PdfViewer != null)
    // Assigned the stream to the "PdfDocumentStream" property.
    PdfViewer.DocumentSource = pdfStream;
}

The document will now be open in your application.

Step 5: Auto-save edited PDF back to S3

  1. After making modifications to the file, save the document as a stream using the PDF Viewer.
// Create a new memory stream to hold the saved PDF document
Stream savedStream = new MemoryStream();

if (PdfViewer != null)
// Asynchronously save the current document content into the memory stream
await PdfViewer.SaveDocumentAsync(savedStream);
  1. Update the original file in Amazon S3 with the modified document stream using TransferUtility. The file will be uploaded back to the specified Amazon S3 bucket asynchronously using the UploadAsync() method by passing the upload request.
// Initialize the TransferUtility, which simplifies file uploads to S3.
var transferUtility = new TransferUtility(s3Client);
// Reset Stream Position before upload.
savedStream.Position = 0;
// Create Upload Request.
var uploadRequest = new TransferUtilityUploadRequest
{
    InputStream = savedStream, // The PDF file stream to upload.
    BucketName = bucketName, // The target S3 bucket name.
    Key = objectKey, // The key(path / filename) for the uploaded object.
    ContentType = "application/pdf" // Set the MIME type to indicate it's a PDF.
};

// Upload the file back to AWS S3 using "UploadAsync" method in the "TransferUtility" class.
await transferUtility.UploadAsync(uploadRequest);

This process is performed automatically whenever a change is detected in the PDF file, using the events provided by the PDF Viewer as explained earlier.

GitHub Example

For full implementation, refer to the following GitHub demos.

Conclusion

Auto-saving PDF edits is a practical and user-focused feature that improves the reliability and usability of document-based applications by ensuring that user changes, such as annotations and form field updates, are preserved automatically and seamlessly.

By combining the cross-platform capabilities of .NET MAUI with the rich editing features of Syncfusion® PDF Viewer, this implementation enables a responsive and event-driven workflow that integrates smoothly with MVVM architecture and asynchronous programming. This allows developers to build intuitive and efficient PDF editing experiences without manual saving actions.

Furthermore, this solution can be easily extended to integrate with other cloud-based storage platforms such as Azure Blob Storage, Dropbox, or Google Cloud, enabling secure backups, cross-device access, and real-time synchronization.

Existing customers can download the new version of Essential Studio® on the license and downloadspage. If you are not a Syncfusion® customer, try our 30-day free trial to check our incredible features.

If you require assistance, please don’t hesitate to contact us via our support forum, support portal, or feedback portal. We are always eager to help you!

This article was originally published at Syncfusion.com.

0
Subscribe to my newsletter

Read articles from syncfusion directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

syncfusion
syncfusion

Syncfusion provides third-party UI components for React, Vue, Angular, JavaScript, Blazor, .NET MAUI, ASP.NET MVC, Core, WinForms, WPF, UWP and Xamarin.