Telerik blogs
DotNetT2 Light_1200x303

In our latest release, we took our first steps towards giving you the ability to edit PDFs in Telerik UI for WPF. Play around with the beta and let us know what you think.

With R2 2020 we kickstarted a brand-new initiative in Telerik UI for WPF—unifying the underlying architecture of PdfViewer and PdfProcessing to allow for feature parity. This is the first step towards enabling editing functionality into the PdfViewer, and in this blog post we will walk you through the power of this unified model.

During past releases, our team worked hard to adapt the RadPdfViewer for WPF to work with the RadPdfProcessing library model. While it was a challenging task to change the model of a mature control and keep its public API, your invaluable feedback demonstrated that this would be a beneficial for your development scenarios

Are you curious about the result of our efforts? I cannot wait to show it to you! Something I must mention before starting, though, is that this change is currently in a beta state, and you will need to enable the new model explicitly. We continue polishing and testing it to ensure that the change in the model will not affect any of the existing customers before applying the change officially. And here is the place to say that your feedback will be precious for us.

Single PdfFormatProvider and Single RadFixedDocument

The unification of the models enables you to work with the same RadFixedDocument instance, no matter which of the two components you need. In the previous versions, if you needed to import a document with PdfProcessing so you can edit it and then show it in PdfViewer, you had to export the PdfProcessing document and then import it in PdfViewer. That operation was a big pain in the usage of the components but is not needed anymore with the new model! You can import the document, edit it, and just assign it to PdfViewer:

PdfFormatProvider pdfFormatProvider = new PdfFormatProvider();
RadFixedDocument document = pdfFormatProvider.Import(stream);
 
this.pdfViewer.Document = document;

Let’s now move to the more interesting part of the topic.

Enabling PDF Editing in RadPdfViewer

In this section of the post, I will walk you through the most important parts of setting up RadPdfViewer so that it allows you to add text content to an existing document in the UI. A complete project demonstrating the scenario is available in our SDK repository: Add Document Content.

To enable the user to write content over the visualized document, we will create a custom layer and will add it to the layers collection of PdfViewer. To create a layer that will be used by RadPdfViewer, you will need to implement the IUILayer interface.

public class AddTextUILayer : IUILayer

Once you have implemented it, we have to register the new layer so it can be used by the control through UILayersBuilder:

public class CustomUILayersBuilder : UILayersBuilder
{
    protected override void BuildUILayersOverride(IUILayerContainer uiLayerContainer)
    {
        base.BuildUILayersOverride(uiLayerContainer);
 
        uiLayerContainer.UILayers.AddAfter(DefaultUILayers.ContentElementsUILayer, new AddTextUILayer());
    }
}

And all that is left is to use the new builder:

CustomUILayersBuilder uILayersBuilder = new CustomUILayersBuilder();
ExtensibilityManager.RegisterLayersBuilder(uILayersBuilder);

The new layer will allow us to show a text box on the location where the user clicked and obtain the value they inserted. The most important part of the layer implementation is the SubmitChangesAndRemoveTextBox() method, which is invoked when the text box has been lost its focus. It shows how to update the document using the API of PdfProcessing. Once you have updated it internally, don’t forget to invalidate the UI so that your changes can be respected and visualized to the user. To enable that, we have exposed the PdfViewer.InvalidatePageUI() method.

private void SubmitChangesAndRemoveTextBox(object sender)
{
    TextBox textBox = (TextBox)sender;
 
    textBox.LostFocus -= this.TextBox_LostFocus;
    textBox.KeyDown -= this.TextBox_KeyDown;
 
    this.canvas.Children.Remove(textBox);
 
    string text = textBox.Text;
 
    RadFixedPage page = this.context.Page;
 
    FixedContentEditor editor = new FixedContentEditor(page);
    editor.Position.Translate(this.mouseLocation.X, this.mouseLocation.Y);
    editor.DrawText(text);
 
    RadPdfViewer viewer = this.context.Presenter.Owner as RadPdfViewer;
    if (viewer != null)
    {
        viewer.InvalidatePageUI(page);
    }
 
    this.hasActiveTextBox = false;
}

Here is what the functionality looks like:

PDFViewer

More is Coming. Do You Want to Try?

As I mentioned at the beginning of the post, the functionality is currently in beta version and is not enabled by default as we are still working on polishing it before officially presenting it to all our users. We have provided options to try the new model as we plan to migrate PdfViewer to use it and your feedback always helps us a lot.

Now you can test the new engine and let us know if you find something that you would like to see implemented differently or fixed. We encourage you to test the new behavior of the control and share your feedback with us so we can take any different points of view and scenarios you might have into account before the official change.

Let’s See How to Do That

The easiest option to setup PdfViewer to use the new model is through its default import settings. We have introduced a new property called UsePdfProcessingModel so you can switch between the two models used by the control. Here is how you can set it:

this.pdfViewer.DefaultFormatProviderSettings.UsePdfProcessingModel = true; 

In case you use the PdfFormatProvider class to import the documents into the control, you can use the same setting applied to the format provider:

FormatProviderSettings settings = new FormatProviderSettings(ReadingMode.OnDemand);
settings.UsePdfProcessingModel = true;
PdfFormatProvider provider = new PdfFormatProvider(stream, settings);
RadFixedDocument doc = provider.Import(stream);
this.pdfViewer.Document = doc;

Already using PdfProcessing? No problem! Just assign the imported RadFixedDocument instance to the Document property of RadPdfViewer:

using(var stream=File.OpenRead(filePath))
{
       PdfFormatProvider provider = new PdfFormatProvider();
       provider.ImportSettings = PdfImportSettings.ReadOnDemand;
       RadFixedDocument doc = provider.Import(stream);
       this.pdfViewer.Document = doc;
}

Note

In this release, we are announcing the immediate availability of this new model architecture for RadPdfViewer. It is still in Preview and optional for the time being as we are still working on adding more features and stability. At this point, we are improving the performance of the model and adding caching mechanisms. Once we reach full feature parity, we will then switch to the new model entirely. That is why all the team will be happy if you test the new architecture and share your feedback with us. This will help us ensure that we have covered all customer scenarios and the new model is stable as much as possible.

Try it Out Yourself and Share Your Feedback

Make sure to get the latest version and try out the new model of the RadPdfViewer control for WPF. Don't be shy and share your feedback! We are more than excited to hear what you think, so if you have any comments or suggestions, we are always here to answer all your questions :). You can use the Telerik UI for WPF Feedback Portal and as always, our ticketing system.

If you haven’t installed the components, hurry up and download a trial today: Try UI for WPF 

We can’t wait to hear your feedback regarding the new engine of RadPdfViewer!


Tanya-Dimitrova
About the Author

Tanya Dimitrova

Tanya Dimitrova is a Tech Support Engineer in the Telerik XAML Team. In her work her main responsibility is to assist clients to implement different scenarios using the document processing libraries and editors. She is passionate in finding new adventures and in her free time enjoys travelling, reading, swimming, dancing or just spending time with friends.

Related Posts

Comments

Comments are disabled in preview mode.