DEV Community

Cover image for Add Digital Signatures to a WPF PDF Viewer with a Click-to-Place eSign Workflow
Calvince Moth for Syncfusion, Inc.

Posted on • Originally published at syncfusion.com on

Add Digital Signatures to a WPF PDF Viewer with a Click-to-Place eSign Workflow

TL;DR: Learn to implement digital signatures inside the Syncfusion WPF PDF Viewer using programmatic techniques. It covers adding a custom eSign button, capturing click positions, generating a signature image, and applying a certificate-based signature. It enables a smooth, secure in-app signing experience even though the viewer does not support signature creation through its UI.

Digital signatures are no longer optional

A digital signature is a cryptographic stamp applied to a document using a certificate containing a private key. It isn’t just about convenience; it’s about trust.

Digital signatures ensure:

  • Document authenticity.
  • Tamper protection.
  • Verified signer identity.

For this reason, digital signatures are standard in legal, financial, and enterprise document workflows.

The smart workaround: In‑app digital signing in WPF PDF Viewer

While Syncfusion WPF PDF Viewer currently supports viewing digital signatures, it does not allow adding or modifying them directly through the UI.

But by combining the Syncfusion WPF PDF Viewer and .NET PDF Library, we can enable programmatic digital signing. We can customize the toolbar, capture user interactions, and embed a certificate-based signature with a dynamically generated image.

Instead of relying on external tools or complex user flows, this solution enables secure, fully integrated digital signing, right inside your WPF PDF Viewer.

Requirements

1. Set up the environment

Install the following prerequisites:

2. Certificate for signing

We need a valid .pfx certificate file that contains a private key. This certificate is used to securely sign the PDF and embed metadata such as the signer’s identity, location, and signing reason.

Add a digital signature using Syncfusion WPF PDF Viewer and .NET PDF Library

This digital signing workflow is built around the following four key steps:

Step 1: Add an eSign button to the toolbar

When the WPF PDF Viewer loads, you can inject a custom eSign button into the existing toolbar.

To keep the UI consistent, we will reuse the style and icon of an existing toolbar item, as shown in the following code.

private void PDFViewer_Loaded(object sender, RoutedEventArgs e)
{
    var toolbar = PDFViewer.Template.FindName("PART_Toolbar", PDFViewer) as DocumentToolbar;
    var stackPanel = toolbar.Template.FindName("PART_ToolbarStack", toolbar) as StackPanel;
    var defaultButton = (Button)((StackPanel)stackPanel.Children[^1]).Children[0];
    var eSignButton = GetButton((Path)defaultButton.Content, defaultButton);
    stackPanel.Children.Add(eSignButton);
}
Enter fullscreen mode Exit fullscreen mode

The GetButton method is responsible for:

  • Creating the new button,
  • Applying the existing style, and
  • Attaching the click event that activates the signing mode.

Step 2: Capture the exact spot where the user clicks

Once the eSign button is clicked, a flag is set to indicate that the next mouse click should trigger signature placement. This will convert the mouse-click coordinates to page-relative positions using the WPF PDF Viewer’s built-in method. So, the signature lands exactly where the user clicked.

This ensures:

  • Pixel‑perfect placement.
  • Support for multi‑page PDFs.
  • A natural “click‑to‑sign” feel users already expect.

Refer to the following code example.

private void PDFViewer_PageClicked(object sender, PageClickedEventArgs args)
{
      if (addSignature)
      {
          var pageIndex = PDFViewer.CurrentPageIndex - 1;
          var pagePoint = PDFViewer.ConvertClientPointToPagePoint(args.Position, pageIndex + 1);
          ApplySignature(pageIndex, pagePoint);
          addSignature = false;
      }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Dynamically generate a signature image

Instead of a generic stamp, this solution creates a meaningful visual signature. It:

  • Generates a runtime image block containing:
    • Signer name.
    • Date and time.
  • Combines it with a handwritten‑style name image.
  • Produces a polished eSign graphic every time.

The visual result meets professional and regulatory requirements.

private void CreateCurrentDataImage()
{
     string text = $"Digitally signed by John\nDate: {DateTime.Now:yyyy.MM.dd\nHH:mm:ss zzz}";
     using var bitmap = new Bitmap(200, 100);
     using var graphics = Graphics.FromImage(bitmap);
     graphics.FillRectangle(Brushes.White, 0, 0, 200, 100);
     graphics.DrawString(text, new Font("Arial", 9), Brushes.Black, new RectangleF(10, 10, 180, 80));
     bitmap.Save(filePath + "DigitalSignatureBlock.png", ImageFormat.Png);
}
Enter fullscreen mode Exit fullscreen mode
private void CombineSignatureAndDataImage()
{
      using var nameImage = Image.FromFile(filePath + "John.png");
      using var signImage = Image.FromFile(filePath + "DigitalSignatureBlock.png");
      using var combinedImage = new Bitmap(nameImage.Width + signImage.Width, Math.Max(nameImage.Height, signImage.Height));
      using var g = Graphics.FromImage(combinedImage);
      g.DrawImage(nameImage, 0, 0);
      g.DrawImage(signImage, nameImage.Width, 0);
      combinedImage.Save(filePath + "ESign.png", ImageFormat.Png);
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Apply a certificate‑based digital signature

Here’s where security comes in. Using the .pfx certificate:

  • A cryptographic digital signature is applied.
  • Metadata is embedded (reason, location, contact information).
  • The signature is rendered visually at the chosen location.

Then, the PDF is saved and reloaded, now officially signed. All of this happens programmatically and securely.

private void ApplySignature(int pageIndex, Point pagePoint)
{
      var page = PDFViewer.LoadedDocument.Pages[pageIndex] as PdfLoadedPage;
      var cert = new PdfCertificate(filePath + "PDF.pfx", "password123");
      var signature = new PdfSignature(PDFViewer.LoadedDocument, page, cert, "Signature");
      var image = new PdfBitmap(filePath + "ESign.png");
      signature.Bounds = new RectangleF((float)pagePoint.X, (float)pagePoint.Y, image.PhysicalDimension.Width, image.PhysicalDimension.Height);
      signature.ContactInfo = "johndoe@owned.us";
      signature.LocationInfo = "Honolulu, Hawaii";
      signature.Reason = "I am the author of this document.";
      signature.Appearance.Normal.Graphics.DrawImage(image, 0, 0);
      using var stream = new MemoryStream();
      PDFViewer.LoadedDocument.Save(stream);
      stream.Position = 0;
      PDFViewer.Load(stream);
}
Enter fullscreen mode Exit fullscreen mode

This article was originally published at Syncfusion.com.

Top comments (0)