office

Previewing Microsoft Office Documents and PDF in WPF using a Preview Handler Host


Hi,

I had recently to implement a mechanism for showing documents into a WPF application. The very first solution was to start a new process using the path of the selected file. The only condition for this to work it’s that the file extension should have been previously registered to be opened with an specific application. A drawback is that the document is shown by an external application that we are not able to handle (at all or at least easily).

Then the client decided showing documents by embedding them into the application. So, I started researching about how to display Portable documents, Word documents, Excel documents into a WPF application. Finally after some research I got to a nice solution which will display many documents formats with the only condition of having the proper software installed into the PC where the application is gonna run.

The Problem
Showing a office document (XLS, DOC, XLSX, DOCX) or portable document (PDF) into a WPF APP.

Remarks
This is not a bullet proof solution, but it is kind extensible for brave developers. The relays on the installed Preview Handlers. For example for visualizing Microsoft Office documents you will have to have installed Microsoft Office in the computer where the application is going to run. It’s the same case for PDF files, where you need to have a Preview Handler installed.
Moreover, the technology of Preview Handler has been built using native code, in order to embedded into a WPF application the app will be hosting WinForm content, this introduces a different set of restrictions about the interaction of the control once it has been instantiated.

The Solution
Preview Handlers is a technology added into Windows Vista, and it’s meant to readonly quick preview of files. It’s available on Windows Explorer
Enabling Previews in Windows Vista Folders
The Microsoft article [1] about Preview Handlers has an utility application which lists the available preview handlers in your system. Moreover after some research, I found the first implementation in [2] which was using Windows Forms and C# for development. Finally I found a more elaborated solution from Coding4Fun [3]. Since this point the solution for WPF was straightforward because it was only matter of loading a WinForm contro into WPF by using Interop components.

1) Grab the code from http://c4fdevkit.codeplex.com/ project. To use the Preview Handler Host you will need only two projects.
/Preview Handlers/Source/VCS/PreviewHandlerFramework
/Preview Handlers/Source/VCS/PreviewHandlerHost

Compile them and the create a new WPF project. The codeplex project hasn’t been updated in awhile, thus you’re more likely to have to update the solution file to a new version of visual studio.

2) Add to your WPF application (or library) a reference to WindowsFormIntegration library. This will allow the application to host WinForm controls. Also add System.Windows.Forms since it will be required by the Preview Handler libraries.

3) The use the WindowsFormsHost tag to embed the PreviewHandlerHostControl as the follwing XAML shows:


        <button></button>

            <C4F_DevKit_PreviewHandler_PreviewHandlerHost:PreviewHandlerHostControl x:Name="previewHandlerHostControlInstance" />

4) Finally our C# code that for our sample is quite simple. We just select a file and let the PreviewHandlerHost control do the work.

using System;
using System.Windows;

namespace PreviewHandlerWpfApplication
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var dlg = new Microsoft.Win32.OpenFileDialog();
            if (dlg.ShowDialog().Value)
            {
                previewHandlerHostControlInstance.FilePath = dlg.FileName;
            }
        }
    }
}

Here is an screenshot of my mighty document viewer:

Sample.Word.Document.Capture

Finally the code is available at GitHub https://github.com/hmadrigal/playground-dotnet/tree/master/MsDesktop.PreviewHandlers Have fun!

References

 

 

Advertisements