Monday, June 24, 2013

Using the Adobe Pdf Reader control in WPF

Important: This will not work if your application targets 64 bit. It will only work as a 32bit app as the AcroPdf.dll is a 32 bit dll.

1. Create a WPF Control Library

2. Add a Windows Forms user control

3. Open the user-control form.

4. In the toolbox, right click and choose “Choose Items…”

5. On the “COM Components” tab, select “Adobe PDF Reader”

image

6. Drag the “Adobe PDF Reader” from the toolbox on the user-control.
Name the control that was added on to the form as "axAcroPdf”

7. Make sure the Anchors are set to “Top, Left” and that Dock is set to “Fill”
image

8. Add the following code to the code behind:

		private AxAcroPDFLib.AxAcroPDF AdobeAcrobatPDfControl
		{
			get
			{
				return this.axAcroPDF;
			}
		}
 
		public void LoadFile(string pdfFilePath)
		{
			AdobeAcrobatPDfControl.LoadFile(pdfFilePath);
		}

8. Create a WPF UserControl. Name it WpfAcrobatCtrl.

9. Drag a WindowsFormsHost WPF control onto the design surface.

10. Set the following properties on the WindowsFormsHost control:
Width and Height to Auto
HorizontalAlignment and VerticalAlignment to Stretch
Name: wpfWindowsFormsHostCtrl.

11. Add the following code to the code behind of the WPF control:

public static readonly DependencyProperty FilePathProperty
			= DependencyProperty.Register("FilePath", typeof(string), typeof(WpfAcrobatCtrl), (PropertyMetadata)new FrameworkPropertyMetadata((object)null, new PropertyChangedCallback(WpfAcrobatCtrl.FilePathChanged)));
 
 
		private string _filePath = string.Empty;
		private CustomAcrobatCtrl _customAcrobatCtrl;
	
		
		private static void FilePathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			((WpfAcrobatCtrl)d).FilePathChanged((string)e.OldValue, (string)e.NewValue);
			CommandManager.InvalidateRequerySuggested();
		}
 
		public WpfAcrobatCtrl()
		{
			InitializeComponent();
			_customAcrobatCtrl = new CustomAcrobatCtrl();
			wpfWindowsFormsHostCtrl.Child = _customAcrobatCtrl;
 
		}
 
		public string FilePath
		{
			get
			{
				return _filePath;
			}
			set
			{
				this.SetValue(FilePathProperty, value);
			}
		}
 
 
		private void FilePathChanged(string oldFilePath, string newFilePath)
		{
			_filePath = newFilePath;
			_customAcrobatCtrl.LoadFile(_filePath);
		}

12. Create a new WPF Window.

13. Drag and drop the WpfAcrobatCtrl onto the design surface.

14. Set the file-path in XAML or code-behind.

Eg: wpfAcrobatCtrl.FilePath = "C:\\test.pdf";

or in XAML: <WpfAcrobat:WpfAcrobatCtrl x:Name="wpfAcrobatCtrl" Margin="0" FilePath="C:\\test.pdf"/>

That’s all!

Note: The above code adds a little extra stuff for the dependency property “FilePath”. This allows for setting the file path via XAML (which was important for me as I needed to be able bind to the property).

Note 2: If you try and use the AcroPdf.dll in a 64 bit app, you will get the following error: {"Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))"}

4 comments:

  1. I tried use this control but not compile

    Whats CustomAcrobatCtrl ?

    private CustomAcrobatCtrl _customAcrobatCtrl;

    ReplyDelete
  2. yes what is CustomAcrobatCtrl ?

    ReplyDelete
  3. "CustomAcrobatCtrl" is the name of the custom control that you would have created in step (2): Add a Windows Forms user control

    ReplyDelete
  4. How do you from stream?

    InitializeComponent();
    var assembly = Assembly.GetExecutingAssembly();
    var resourceName = fileName;

    using (Stream stream = assembly.GetManifestResourceStream(resourceName))
    using (StreamReader reader = new StreamReader(stream))
    {
    string result = reader.ReadToEnd();


    this.axAcroPDF1.LoadFile(resourceName);

    }

    ReplyDelete

Remember, if you want me to respond to your comment, then you need to use a Google/OpenID account to leave the comment.