Alessandro Del Sole's Blog

{ A programming space about Microsoft® .NET® }
posts - 1908, comments - 2047, trackbacks - 352

My Links

News

Your host

This is me! Questo spazio è dedicato a Microsoft® .NET®, di cui sono molto appassionato :-)

Cookie e Privacy

Disabilita cookie ShinyStat

Microsoft MVP

My MVP Profile

Microsoft Certified Professional

Microsoft Specialist

Xamarin Certified Mobile Developer

Il mio libro su VB 2015!

Pre-ordina il mio libro su VB 2015 Pre-ordina il mio libro "Visual Basic 2015 Unleashed". Clicca sulla copertina per informazioni!

Il mio libro su WPF 4.5.1!

Clicca sulla copertina per informazioni! E' uscito il mio libro "Programmare con WPF 4.5.1". Clicca sulla copertina per informazioni!

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.
If you're not an Italian user, please visit my English blog

Le vostre visite

I'm a VB!

Guarda la mia intervista a Seattle

Follow me on Twitter!

Altri spazi

GitHub
I miei progetti open-source su GitHub

Article Categories

Archives

Post Categories

Image Galleries

Privacy Policy

WPF: Visualizzare documenti PDF sfruttando l'OCX di Adobe Reader

Capita piuttosto spesso la necessità di dover visualizzare documenti in formato Pdf in molte applicazioni e quelle WPF non sono escluse. Ci sono molte librerie per file Pdf basate su .NET, alcune anche open source, principalmente per la generazione piuttosto che per la visualizzazione di tale formato. A tal proposito in alcuni casi può essere comodo ricorrere al componente di Adobe Reader, soprattutto in scenari come quello che sto per descrivere.

Nel mio caso ho tanti pc in una LAN; su ogni pc è installato Adobe Reader per default. Questo è fondamentale perchè l'ActiveX di Adobe Reader non è ridistribuibile (anche se in questo tipo di contesto può sembrare strano), per cui la preventiva presenza del reader sul sistema diventa un prerequisito. Se questa può sembrare una limitazione, alla tecnica che sto per descrivere se ne può aggiungere un'altra: si ricorre all'interoperabilità con Windows Forms. In WPF, infatti, non è possibile utilizzare direttamente controlli ActiveX sulle Window ma è necessario utilizzare controlli Win Forms da ospitare negli oggetti WPF. Diciamo che è un sistema semplificato, che può rendere la vita altrettanto semplice a seconda del contesto. Diciamo anche che, invece di ricorrere ad assembly esterni, faccio uso di assembly di .NET Framework e di componenti già presenti sul sistema.

Detto questo, ipotizziamo di avere un'applicazione WPF. Il primo passaggio da eseguire è quello di aggiungere al progetto un controllo utente Windows Forms, come in figura:

Una volta che il controllo utente viene aggiunto al progetto, nella Toolbox compaiono gli elementi Windows Forms. Facciamo clic destro su una delle schede disponibili e selezioniamo Choose Items dal menu contestuale. Nella dialog successiva, apriamo la scheda dei componenti COM e selezioniamo quello di Adobe Reader come in figura:

Noteremo quindi la presenza dell'icona di Adobe Reader nella scheda prescelta in Toolbox, quindi trasciniamo tale controllo sullo user control. In questa fase Visual Studio genera due wrapper: AxInteropAcroPDFLib.dll e InteropAcroPDFLib.dll, il primo dei quali si occupa, in particolare, di importare le funzionalità del controllo ActiveX rendendolo fruibile da .NET. Questi due assembly sono fondamentali perchè, se da un lato il componente del visualizzatore di Adobe Reader non è ridistribuibile, questi invece dovranno essere ridistribuiti insieme all'applicazione. A questo punto passiamo al codice dello user control e scriviamo il costruttore come segue:

    Public Sub New(ByVal documentName As String)

 

        ' This call is required by the designer.

        InitializeComponent()

 

        ' Add any initialization after the InitializeComponent() call.

 

        '...implementare qui la logica di validazione

        'del file name

 

        Try

            AxAcroPDF1.LoadFile(documentName)

        Catch ex As Exception

            'Implementare la gestione delle eccezioni

            System.Windows.Forms.MessageBox.Show(ex.Message)

        End Try

    End Sub

Notate che la classe AxAcroPDF rappresenta un'istanza del visualizzatore di Adobe Reader e offre alcuni metodi per gestirlo, per i quali vi lascio la curiosità degli approfondimenti. Ci interessa in particolare il metodo LoadFile a cui va passato il nome completo del documento. Segnalo solo il metodo setShowToolbar che, se riceve False, nasconde la barra degli strumenti di Adobe Reader. Così facendo non consentiremo neanche la stampa, però in questo modo rendiamo invisibile anche il pulsante per il salvataggio di copie locali. Io l'ho utilizzato per evitare che l'utente potesse salvare copie del documento, che risiede su un server, sulla propria macchina per ragioni di privacy.

Torniamo alla finestra WPF all'interno della quale visualizzeremo il documento. In primo luogo, dalla Toolbox trasciniamo un elemento WindowsFormsHost. Questa operazione aggiungerà i riferimenti necessari all'interoperabilità e la seguente definizione nello XAML:

    <Grid>

        <my:WindowsFormsHost Name="WinFormsHost1" />

    </Grid>

L'ultima operazione da compiere è istanziare, nel file di code-behind, il controllo utente creato in precedenza e assegnare tale istanza alla proprietà Child del WindowsFormsHost:

    'Uso VB 2010, quindi no more underscore a parte Handles :-)

    Private Sub Window_Loaded(ByVal sender As System.Object,

                              ByVal e As System.Windows.RoutedEventArgs) _

                              Handles MyBase.Loaded

        'Sostituire con un nome di file valido:

        Dim viewer As New PdfViewer("MyFile.pdf")

        Me.WinFormsHost1.Child = viewer

    End Sub

Nel momento in cui la finestra verrà caricata, avrà un aspetto simile al seguente:

Così facendo siamo riusciti a visualizzare un Pdf in una finestra WPF senza ricorrere a librerie esterne, purché Adobe Reader sia già installato sulla macchina. Se volete scaricare il progetto utilizzato in questo post, lo potete trovare a questo indirizzo.

Alessandro

Print | posted on lunedì 19 aprile 2010 21:40 | Filed Under [ Windows Presentation Foundation ]

Powered by:
Powered By Subtext Powered By ASP.NET