This is a migrated thread and some comments may be shown as answers.

RadPdfViewer document Binding in MvvM ?

19 Answers 861 Views
PDFViewer
This is a migrated thread and some comments may be shown as answers.
F1Soft
Top achievements
Rank 1
F1Soft asked on 23 Apr 2018, 05:25 AM

Hello admins.

I have a problem with RadPdfViewer.

normal case is good.

--MainWindow.cs------------------------------------------

    public partial class MainWindow : Window
    {
        string pdfFilePath = @"C:\Temp\PDFs\20170707 learnwpf.pdf";

        public MainWindow()
        {
            InitializeComponent();
            
            this.pdfViewer.DocumentSource = new PdfDocumentSource(new System.Uri(pdfFilePath, System.UriKind.RelativeOrAbsolute));
        }
    }

------------------------------------------------------------

 

But, in MvvM not working.

--MainWindow.xaml------------------------------------

<Window x:Class="TelerikWpfPDFViewerBinding.MainWindow"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
                Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <telerik:RadPdfViewerToolBar RadPdfViewer="{Binding ElementName=pdfViewer, Mode=OneTime}" SignaturePanel="{Binding ElementName=signaturePanel, Mode=OneTime}"/>
            <telerik:SignaturePanel x:Name="signaturePanel" PdfViewer="{Binding ElementName=pdfViewer, Mode=OneWay}" Grid.Row="1"/>
            <telerik:RadPdfViewer x:Name="pdfViewer" 
                                  DataContext="{Binding CommandDescriptors, ElementName=pdfViewer}" 
                                  telerik:RadPdfViewerAttachedComponents.RegisterSignSignatureDialog="True" 
                                  telerik:RadPdfViewerAttachedComponents.RegisterFindDialog="True" 
                                  Grid.Row="2" 
                                  telerik:RadPdfViewerAttachedComponents.RegisterSignaturePropertiesDialog="True" 
                                  telerik:RadPdfViewerAttachedComponents.RegisterContextMenu="True"
                                  Document="{Binding PDFDocument,Mode=TwoWay}"/>
        </Grid>

    </Grid>
</Window>

-------------------------------------------------------------------------------------

--MainWindow.xaml.cs-------------------------------------------------------

namespace TelerikWpfPDFViewerBinding
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel();
        }
    }
}

---------------------------------------------------------------------------------

--MainWindowViewModel.cs-------------------------------------------

using System.IO;

using Telerik.Windows.Controls;

using Telerik.Windows.Documents.Fixed.FormatProviders;
using Telerik.Windows.Documents.Fixed.FormatProviders.Pdf;
using Telerik.Windows.Documents.Fixed.Model;

namespace TelerikWpfPDFViewerBinding
{
    public class MainWindowViewModel: ViewModelBase
    {
        private RadFixedDocument _PDFDocument;
        public RadFixedDocument PDFDocument {
            get { return _PDFDocument; }
            set {
                _PDFDocument = value;
                OnPropertyChanged("PDFDocument");
            }
        }
        public MainWindowViewModel()
        {
            string pdfFilePath = @"C:\Temp\PDFs\20170707 learnwpf.pdf";
            LoadPDFDocument(pdfFilePath);
        }

        private void LoadPDFDocument(string pdfFilePath)
        {
            MemoryStream stream = new MemoryStream();

            using (Stream input = File.OpenRead(pdfFilePath))
            {
                input.CopyTo(stream);
            }

            FormatProviderSettings settings = new FormatProviderSettings(ReadingMode.OnDemand);
            PdfFormatProvider provider = new PdfFormatProvider(stream, settings);
            PDFDocument = provider.Import();
        }

    }
}
----------------------------------------------------------------------------------------------

Where am I wrong?

thanks.

19 Answers, 1 is accepted

Sort by
1
Tanya
Telerik team
answered on 25 Apr 2018, 09:09 PM
Hi,

Thank you for sharing the code.

While in code-behind both, Document and DocumentSource properties can be used, to bind a document to PdfViewer, you will need to use the DocumentSource property. More information about the different approaches that can be used to import a document in RadPdfViewer is available in the Showing a File help topic.

Additionally, when the UI of RadPdfViewer is used, the data context of the control points to its CommandDescriptors, which is necessary for the commands to work when the users interact with the UI. If you need to have the commands and the document bound to the control, you will need to add the CommandDescriptors of RadPdfViewer as a property in the view model. I prepared a sample project to demonstrate how exactly you can achieve that. Please, find it as an attachment to this reply.

Hope this is helpful.

Regards,
Tanya
Progress Telerik
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which you to write beautiful native mobile apps using a single shared C# codebase.
0
F1Soft
Top achievements
Rank 1
answered on 26 Apr 2018, 04:35 AM

thank you Tanya.

I had try DocumentSource already. I found answer saw after that your file. It works after remove DataContext line. ^^;

--------------------------------------------------------------------------------------

<telerik:RadPdfViewer x:Name="pdfViewer" 
                                  DataContext="{Binding CommandDescriptors, ElementName=pdfViewer}" 
                                  telerik:RadPdfViewerAttachedComponents.RegisterFindDialog="True" 
                                  Grid.Row="1" 
                                  telerik:RadPdfViewerAttachedComponents.RegisterContextMenu="True"
                                  DocumentSource="{Binding PDFDocument,Mode=TwoWay}"/>

--------------------------------------------------------------------------------------

another question:

pdfViewer.GoToPage(10);

how to implementing in MvvM?

0
F1Soft
Top achievements
Rank 1
answered on 26 Apr 2018, 05:15 AM

It works like this:

        public void SetPage(object page)
        {
            if (CommandDescriptors.FixedDocumentViewer != null)
            {
                int iPage = 0;
                if( int.TryParse(page.ToString(), out iPage) )
                    CommandDescriptors.FixedDocumentViewer.GoToPage(iPage);
            }
        }

0
Tanya
Telerik team
answered on 30 Apr 2018, 10:46 AM
Hello,

Yes, I can confirm that the approach you have found is a feasible one and should be working as expected.

Regards,
Tanya
Progress Telerik
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which you to write beautiful native mobile apps using a single shared C# codebase.
0
Kevin
Top achievements
Rank 1
answered on 08 Apr 2019, 03:55 PM
Hi Tanya,

I am trying to open a PDF document in WPF via Telerik's native pdfDocumentViewer as well. (I want the user not to need Microsoft Word installed, or Adobe Acrobat pdf viewer installed)

I downloaded the demo project you attached and tailored it to my project, however all I see when I click the "show pdf button" is the PDfViewerDemo.MainWindow.xml I created for it, it builds fine, I just don't see RadPDFViewerToolBar, no PDF data or any of the Signature Properties/Context Menu options...
I included all my references Telerik.Windows.Controls, Windows.Documents.Fixed, FixedDocumentViewersUI etc.

.NET Framework is version 4.5 and I'm using Visual Studio 2015
Could it be the 'LoadPDFDocument' function, maybe the memory stream isn't grabbing the pdf? I expected to see at least the picture attached in the XAML design view, but it was just showing a blank MainWindow.

Thanks for your help!

Sincerely
Kevin

0
Tanya
Telerik team
answered on 11 Apr 2019, 08:57 AM
Hi Kevin,

Such behavior can be observed when the NoXaml assemblies are referred. Can you please verify that the reference of the project point to the Binaries folder of the installation instead of the Binaries.NoXaml one? You can find more information about the two types and approaches in the Xaml vs NoXaml help topic.

Hope this is helpful.

Regards,
Tanya
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Kevin
Top achievements
Rank 1
answered on 11 Apr 2019, 07:43 PM
Hi Tanya,

Thank you for your response and pointing me into the direction of the xaml vs. noxaml content. I believe that is where the problem lies.

At my home laptop I installed Telerik myself on VisualStudio2017 and most likely referenced the xaml .dlls which is why I was able to build, invoke the pdf and even see the pdfViewerToolbar in design mode.

At my work I am using Telerik on VS2015 but only the nonxaml dlls were copied over via a ‘Telerik’ folder on a storage device with like 40 of the dlls we wanted to use for GUIs. The Progress/Telerik UI for WPF wasn't installed (thus no .msi, .zip, 'Binaries', 'Binaries.NoXaml' or 'Themes.Implicit' folders), so I don’t have access to the xaml dlls, we have just the No Xaml dlls.
That being said, all I see in my design view for main window.xaml is the title bar and a blank window pane, same thing when I run the project.


I referenced the Office_Black theme and included the Application.Resource in App.xaml but still no luck… :/

What can I do if I don't have access to the Xaml .dlls at my workplace?

Thanks so much for your help

Sincerely
Kev
0
Tanya
Telerik team
answered on 12 Apr 2019, 07:37 AM
Hello Kevin,

If you would like to use the NoXaml approach, you will need to merge the resources containing the styles for the control so it can be rendered. This approach is described in the Setting a Theme Using Implicit Styles topic and here is an example of setting the resources for RadPdfViewer and its UI:
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/Telerik.Windows.Themes.Office2013;component/Themes/System.Windows.xaml" />
            <ResourceDictionary Source="/Telerik.Windows.Themes.Office2013;component/Themes/Telerik.Windows.Controls.xaml" />
            <ResourceDictionary Source="/Telerik.Windows.Themes.Office2013;component/Themes/Telerik.Windows.Controls.Input.xaml" />
            <ResourceDictionary Source="/Telerik.Windows.Themes.Office2013;component/Themes/Telerik.Windows.Controls.Navigation.xaml" />
            <ResourceDictionary Source="/Telerik.Windows.Themes.Office2013;component/Themes/Telerik.Windows.Controls.FixedDocumentViewers.xaml" />
            <ResourceDictionary Source="/Telerik.Windows.Themes.Office2013;component/Themes/Telerik.Windows.Controls.FixedDocumentViewersUI.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

Hope this information will help you.

Regards,
Tanya
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Kevin
Top achievements
Rank 1
answered on 30 Apr 2019, 12:31 AM

Hello Tanya,

This worked perfectly! :)  Thank you so much for you help. My team was using Windows 8 theme and it looks like explicitly merging the resources containing the styles from Office2013 did the trick.

Last question, if we want to implement bookmarks with the pdfViewer is this possible? I have created an enum list of bookmark names that I would like to open to specific pages/sections of the PDF that is being viewed.

I see the blog post by Georgi Georgiev (https://www.telerik.com/blogs/navigating-easily-with-new-pdf-bookmarks-support-in-radpdfviewer-for-wpf) notes that the commands for this could be invoked from the code using:
this.pdfViewer.CommandDescriptors.SyncCurrentBookmarkItemCommandDescriptor.Command.Execute(null);
- are you familiar with this method?

Thanks again Tanya - have a great week

Sincerely

Kevin

0
Georgi
Telerik team
answered on 02 May 2019, 04:50 PM
Hi Kevin,

The resources for each theme are defined in a resource dictionary for the theme. In order to avoid any visualization issues or errors, you may merge the dictionary for the particular theme you will be using. For example, if you pick up to apply the Windows8 theme, you can merge the .xaml files from Windows8 theme.

As of R3 2018, RadPdfViewer enables you to open documents and show the bookmarks they contain in a bookmarks panel. In order to show the document bookmarks you can use the RadPdfViewerNavigationPane control, as can be seen in Visualizing Bookmarks section of the documentation. The SyncCurrentBookmarkItemCommand is used to synchronize the bookmarks panel to the current bookmark, depending on the current page RadPdfViewer is scrolled to. When the command is executed, this will lead to selecting the bookmark in the bookmarks panel corresponding to the current viewport in RadPdfViewer.

RadPdfViewer is designed for visualization purposes and not for editing. For this reason, creating and editing of bookmarks is not supported functionality. We have logged a feature request for our PdfProcessing library: Support for document outline (bookmarks), where you can vote to increase the priority and subscribe to be notified for any status updates.

I hope this helps.

Regards,
Georgi
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Kevin
Top achievements
Rank 1
answered on 13 May 2019, 10:12 PM

Hi Georgi

Thank you for your response and for the depth of the answer. I appreciate it
I have expressed my interest to increase the priority of the bookmarks support for pdfViewers, in the link you provided.

I will keep an eye out for status updates.

Thanks

Sincerely

Kev

0
Georgi
Telerik team
answered on 16 May 2019, 04:22 PM
Hi Kevin,

In the PDF document model, the bookmarks are represented as a tree hierarchy defined in a document level property. Each bookmark item of the tree hierarchy is consisted of a destination, pointing to document location, and bookmark title, used when visualizing the bookmarks.

Since the bookmarks are part of the document model you can visualize them when the document is imported using RadPdfViewer. When importing a document containing bookmarks, the RadPdfViewer uses the RadPdfViewerNavigationPane control in order to display the document bookmarks.

Another scenario is to create or edit the bookmarks hierarchy and export the resultant PDF document. This approach is related to the mentioned item for our PdfProcessing library.

Can you please elaborate more on the scenario you are currently encountering. Is your requirement related to visualizing PDF bookmarks only or creating and editing functionality will be needed?

Regards,
Georgi
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Kevin
Top achievements
Rank 1
answered on 21 Jun 2019, 02:28 PM

Hi Georgi,

Thank you for your response

My requirement is only visualizing bookmarks on the navigation pane (see attached). A bonus "icing on the cake" would be if I could program event handlers on button clicks in my C# WPF Application to open the PDF document to specific bookmarks/page locations in the pdf document; like each button correlating it's own section in the pdf.

When I code up the <telerik:RadPDfViewerNavigationPane RadPdfViewer = "{Binding ElementName=pdfViewer, Mode=OneTime...

-it gives me an error of "RadPdfViewerNavigationPane does not exist in namespace schemas.telerik.com/2008/XAML"

Any idea what could be happening?

Thanks Georgi, have a great weekend

Sincerely

Kev

0
Georgi
Telerik team
answered on 26 Jun 2019, 01:07 PM
Hi Kev,

PDF bookmarks are introduced in RadPdfViewer with R3 2018. Can you share the version you are currently using? If you are using an older version, you will need to update your version to take advantage of the PDF bookmarks functionality.

When a document is loaded in RadPdfViewer, the bookmarks collection can be accessed from the RadPdfViewerNavigationPane's ViewModel. The ViewModel exposes a Bookmarks property, which represents a collection of the loaded bookmark items. In order to navigate to particular bookmark, you can use the ActivateBookmarkItemCommand exposed in the CommandDescriptors property of RadPdfViewer. For example, you can find the desired bookmark by iterating the collection recursively and activate it using the command:
BookmarksTabItemViewModel bookmarksTabItemViewModel = this.radPdfViewerNavigationPane.ViewModel.BookmarksTabItemViewModel;
 
BookmarkItemViewModel result = null;
foreach (var bookmarkItemViewModel in bookmarksTabItemViewModel.Bookmarks)
{
    result = bookmarkItemViewModel.BookmarkItemModel.Title == bookmarkTitle ? bookmarkItemViewModel : this.FindBookmark(bookmarkItemViewModel, bookmarkTitle);
 
    if (result != null)
    {
        break;
    }
}
 
if (result != null)
{
    ICommand activateBookmark = this.pdfViewer.CommandDescriptors.ActivateBookmarkItemCommandDescriptor.Command;
    activateBookmark.Execute(result.BookmarkItemModel);
}

And the FindBookmark  method:
private BookmarkItemViewModel FindBookmark(BookmarkItemViewModel root, string targetName)
{
    BookmarkItemViewModel result = null;
 
    foreach (var node in root.Children)
    {
        if (node.BookmarkItemModel.Title == targetName)
        {
            result = node;
        }
 
        BookmarkItemViewModel childResult = this.FindBookmark(node, targetName);
 
        if (childResult != null)
        {
            result = childResult;
        }
    }
 
    return result;
}

I hope this helps.

Regards,
Georgi
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Mohan
Top achievements
Rank 1
answered on 07 Oct 2019, 12:21 PM

Hi,

I'm unable to get the Document from the PDFViewer. 

I tried different approaches but nothing worked.

Approach 1:

Stream str = App.GetResourceStream(new System.Uri("PdfViewerDemo;component/SampleData/Sample.pdf", System.UriKind.Relative)).Stream;

this.pdfViewer.DocumentSource = new PdfDocumentSource(str);

 

Approach 2:

this.pdfViewer.DocumentSource = new PdfDocumentSource(new System.Uri("PdfViewerDemo;component/SampleData/Sample.pdf", System.UriKind.Relative));

 

In both the cases, we are able to fetch the DocumentSource object but the Document is null.

We tried few other approaches mentioned in the below link:

https://docs.telerik.com/devtools/wpf/controls/radpdfviewer/showing-a-file#setting-documentsource-in-code-behind

Can you please help us in resolving this issue?

0
Georgi
Telerik team
answered on 10 Oct 2019, 10:07 AM

Hello Mohan,

When a PdfDocumentSource instance is created using the URI or Stream constructor, the PDF document is imported and loaded asynchronously. For this reason, the Document property will be applied later in time. In order to access the applied document instance, you can subscribe for the DocumentChanged event of RadPdfViewer:

this.pdfViewer.DocumentChanged += PdfViewer_DocumentChanged;
...
private void PdfViewer_DocumentChanged(object sender, DocumentChangedEventArgs e)
{
    RadFixedDocument doc = e.NewDocument;
}

I hope this will help you achieve the desired result.

Regards,
Georgi
Progress Telerik

Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Mohan
Top achievements
Rank 1
answered on 11 Oct 2019, 11:38 AM

Hi Georgi,

We tried the approach which you have suggested but still we are unable to view the PDF in the WPF window.
I have attached step wise snapshot of the execution of the code:

0
Mohan
Top achievements
Rank 1
answered on 11 Oct 2019, 11:50 AM

Hi Georgi,
I have missed some file before, which i have attached here.

Can you please look into it and let us know how to resolve the issue?

0
Georgi
Telerik team
answered on 16 Oct 2019, 11:30 AM

Hi Mohan,

Please, excuse me for misunderstanding the scenario in my previous answer.

After taking a look at the screenshots you have provided, I couldn't see any problems with the code. However, the issue with the non-visualized content may be caused if you are referencing the NoXaml binaries. The NoXaml binaries are the lightweight option compared to the standard ones as they don't contain the styles for the controls. However, in order to set up a NoXaml assembly, you will need to reference an additional theme dll and merge the ResourceDictionaries with the styles for each control dll as can be seen in the Setting a Theme article. More information on the topic can be found in the Xaml vs NoXaml article in the documentation.

I hope this helps.

Regards,
Georgi
Progress Telerik

Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
PDFViewer
Asked by
F1Soft
Top achievements
Rank 1
Answers by
Tanya
Telerik team
F1Soft
Top achievements
Rank 1
Kevin
Top achievements
Rank 1
Georgi
Telerik team
Mohan
Top achievements
Rank 1
Share this question
or