Universal Windows Platform – PdfView App

PdfView App demonstrates how to create an application which will allow you to read and navigate through PDF Documents and its pages.

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu find and select Visual Studio 2017.

vs2017

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project
vs2017-new-project-window

Step 4

Then in New Universal Windows Project you need to select the Target Version this should be at least the Windows 10, version 1803 (10.0; Build 17134) which is the April 2018 Update and the Minimum Version to be the same.

vs2017-target-platform

The Target Version will control what features your application can use in Windows 10 so by picking the most recent version you’ll be able to take advantage of those features. To make sure you always have the most recent version, in Visual Studio 2017 select Tools Extensions and Updates… then and then see if there are any Updates

Step 5

Once done select from the Menu, Project, then Add New Item…

vs2017-project-add-new-item

Step 6

From the Add New Item window select Visual C#, then Code from Installed then select Code File from the list, then type in the Name as Library.cs before selecting Add to add the file to the Project

vs2017-add-new-item-library

Step 7

Once in the Code View for Library.cs the following should be entered:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Data.Pdf;
using Windows.Foundation;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using Windows.UI.Popups;
using Windows.UI.Xaml.Media.Imaging;

public class Library
{
    private const string app_title = "PdfView App";

    private PdfDocument _document = null;

    public void Show(string content, string title)
    {
        IAsyncOperation<IUICommand> command = new MessageDialog(content, title).ShowAsync();
    }

    public async Task<uint> OpenAsync()
    {
        uint pages = 0;
        try
        {
            _document = null;
            FileOpenPicker picker = new FileOpenPicker()
            {
                SuggestedStartLocation = PickerLocationId.DocumentsLibrary
            };
            picker.FileTypeFilter.Add(".pdf");
            StorageFile open = await picker.PickSingleFileAsync();
            if (open != null)
            {
                _document = await PdfDocument.LoadFromFileAsync(open);
            }
            if (_document != null)
            {
                if (_document.IsPasswordProtected)
                {
                    Show("Password Protected PDF Document", app_title);
                }
                pages = _document.PageCount;
            }
        }
        catch (Exception ex)
        {
            if (ex.HResult == unchecked((int)0x80004005))
            {
                Show("Invalid PDF Document", app_title);
            }
            else
            {
                Show(ex.Message, app_title);
            }
        }
        return pages;
    }

    public async Task<BitmapImage> ViewAsync(uint number)
    {
        BitmapImage source = new BitmapImage();
        if (!(number < 1 || number > _document.PageCount))
        {
            uint index = number - 1;
            using (PdfPage page = _document.GetPage(index))
            {
                using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
                {
                    await page.RenderToStreamAsync(stream);
                    await source.SetSourceAsync(stream);
                }
            }
        }
        return source;
    }

    public List<int> Numbers(int total)
    {
        return Enumerable.Range(1, total).ToList();
    }
}

The Library Class defines the PdfDocument that can be opened later then there’s a Show method for displaying messages on-screen. The OpenAsync method uses the FileOpenPicker set to open a “.pdf” file and then sets the PdfDocument to be the opened file using PickSingleFileAsync with the LoadFromFileAsync method – if the document has been opened if it is password protected a message will be displayed to say that the example won’t open those, otherwise there’s an Exception handler to detect a PDF document that has failed to open due to being invalid or some other error during opening and this method also returns the number of pages in the PDF document as uint.

There’s a ViewAsync which takes a uint as a parameter and then gets a PdfPage from the document using this and then this is rendered to a BitmapImage using the RenderToStreamAsync to set an InMemoryRandomAccessStream which is used to set the source of the BitmapImage with that page’s contents using SetSourceAsync. Theres also a Numbers method which helps generate a list of page numbers to be used.

Step 8

In the Solution Explorer select MainPage.xaml

vs2017-mainpage-library

Step 9

From the Menu choose View and then Designer

vs2017-view-designer

Step 10

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<Grid Margin="50">
	<Grid.RowDefinitions>
		<RowDefinition Height="Auto"/>
		<RowDefinition Height="*"/>
	</Grid.RowDefinitions>
	<ComboBox Name="Page" Grid.Row="0" HorizontalAlignment="Stretch" SelectionChanged="Page_SelectionChanged"/>
	<ScrollViewer Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center">
		<Image Name="Display" Stretch="None"/>
	</ScrollViewer>
</Grid>
<CommandBar VerticalAlignment="Bottom">
	<AppBarButton Icon="OpenFile" Label="Open" Click="Open_Click"/>
</CommandBar>

MainPage.xaml contains the Open button to allow a PDF Document to be opened and there’s a ComboBox that is populated with all possible page numbers based on the number of pages in the document – when a number is selected that uses the ViewAsync method to get that page. Finally there’s an Image control which is used to display the page and this is contained within a ScrollViewer so if the page is too wide or long it can be scrolled around to view all that page’s contents.

Step 11

From the Menu choose View and then Code

vs2017-view-code

Step 12

Once in the Code View, below the end of public MainPage() { … } the following Code should be entered:

Library library = new Library();

private async void Open_Click(object sender, RoutedEventArgs e)
{
	uint pages = await library.OpenAsync();
	if (pages > 0)
	{
		Page.ItemsSource = library.Numbers(Convert.ToInt32(pages));
		Page.SelectedIndex = 0;
	}
}

private async void Page_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
	uint.TryParse(Page.SelectedItem.ToString(), out uint page);
	Display.Source = await library.ViewAsync(page);
}

Below the MainPage() Method an instance of the Library Class is created, then Open_Click is used to call the OpenAsync Method which returns a uint stating how many pages there are and then populates the ComboBox with values up to that number using the Numbers Method from the Library Class. The Page_SelectionChanged Event responds to selections from the ComboBox and will get the SelectedItem and convert this back to a uint then pass this to the ViewAsync Method of the Library Class and view that page.

Step 13

That completes the Universal Windows Platform Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-local-machine

Step 14

After the Application has started running you can then select Open then you need to select a pdf document, Once done then you can select the ComboBox to choose which page of the document to display but it will start with the first.

ran-pdfview-app

Step 15

To Exit the Application select the Close button in the top right of the Application

vs2017-close

This example was inspired from the Microsoft Universal Windows Platform (UWP) app samples and in particular the PDF document example, the main purpose of this example was to show how easy it is to open and navigate through a PDF Document – although password protected documents aren’t fully supported in the example it would be possible to open these if the correct password was provided to the LoadFromFileAsync method from a TextBox or value. It’s quite easy to support PDF documents this way and could be a useful way of integrating PDF documents into any application using this example as the start of that – you could even have it scroll through all the pages by using multiple Image controls and setting their sources accordingly to each page in the PDF document.

Creative Commons License

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s