Créer un volet d’action dans Word 2007 avec VSTO

Je profite de ma dernière démo que j’ai montrée à la BDC 2009 pour un petit tutorial basique sur l’utilisation de Custom Task Panes dans Word 2009 avec VSTO. Le principe est assez simple : je vais créer un addin applicatif pour word 2007 avec Visual studio 2008. Cet addin ajoutera un onglet au ruban. Cet onglet contient un bouton qui permet de faire apparaitre mon panneau d’action. Le panneau contient au final un contrôle utilisateur maison, pour la démo un "joli" contrôle WPF qui affiche une liste de contacts. De plus le contrôle en question me lève des évènements que je vais utiliser pour ajouter du contenu à mon document Word. Pour commencer…

Téléchargez le code source ici

Visual Studio 2008 propose nativement des modèles de projet office 2003 et 2007. Je choisi donc un nouveau projet "Word 2007 Add-in" :

image

Ensuite j’ajoute un ruban et un bouton pour déclencher l’affichage de mon panneau. Là c’est facile je fais click droit sur mon projet, ajouter un nouvel élément, je choisi dans la rubrique "office" le ruban. J’ouvre le ruban dans le designer et j’ajoute par glissé déposé un bouton :

image

Un simple double click sur ce bouton me génère la méthode qui va intercepter le click sur ce bouton (comme pour n’importe quelle application winform). C’est là que commence la partie un peu plus "ardue". VSTO ne propose pas de designer pour les "custom task panes" et pas de branchement automatique. Il faut le faire par code ! Bon ceci dit c’est fait en quelques étapes :

1) il faut récupérer la référence de la fenêtre en cours. Elle nous sera nécessaire pour créer notre objet de type CustomTaskPane
2) il faut vérifier que le panneau n’a pas été déjà créé pour le document en cours (sinon on aura plusieurs fois le même panneau)
3) on créer un UserControl qui sera le contrôle WinForm affiché dans le panneau. Dans mon cas je crée en plus un contrôle de type ElementHost qui va me permettre d’y intégrer un contrôle WPF. De plus je garde une référence globale sur le contrôle WPF car je vais me brancher sur un de ses événements
4) on crée un objet de type CustomTaskPane et on y insère notre UserControl.

Voilà "l’illustration" de ces étapes par le code :

1) Fenêtre en cours  (on défini aussi un titre à notre panneau pour pouvoir le retrouver) :

// recuperation de la fenetre en cours
        Microsoft.Office.Interop.Word.Window _Window;
        _Window = Globals.ThisAddIn.Application.ActiveDocument.ActiveWindow;

        // titre du panneau
        string _Title;
        _Title = "Mes contacts";

2) Vérification que le panneau n’est pas déjà existant pour le document en cours :

//on verifie que le panneau n'est pas dejà present
        // pour celà on le cherche dans la collection des CustomTaskPanes par son titre et sa fenêtre
        var customPane = Globals.ThisAddIn.CustomTaskPanes.FirstOrDefault(p => p.Title == _Title && p.Window == _Window);
        if (customPane != null)
        {
        customPane.Visible = true;
        return;
        }

Si le panneau à déjà été crée précédemment sur ce document et que l’utilisateur l’a fermé et bien l’instance existe encore, elle est juste cachée. Il suffit donc de remettre le panneau visible.

3) Création du UserControl et paramétrage (j’inclus donc à l’intérieur un contrôle WPF qui pourrait être utilisé de manière totalement indépendante donc je ne détaillerai pas le code de ce contrôle. Sachez juste qu’il récupère une liste d’images dans un dossier local et crée des entités de type "contact" avec l’image, le nom et le prénom.) :

// creation du UserControl à afficher
        UserControl _Control;
        _Control = new UserControl();

        //on y inclut le control WPF
        elementHost = new ElementHost();
        rotator = new ImageRotator();
        elementHost.Child = rotator;
        elementHost.Dock = DockStyle.Fill;
        _Control.Controls.Add(elementHost);
        //on se branche sur l'évènement de ce contole
        rotator.OnDoubleClick += new ContactDoubleClickHandler(rotator_OnDoubleClick);

4) on crée l’objet CustomTaskPane et on l’ajoute à la collection des CustomTaskPane :

// on creer le panneau
        Microsoft.Office.Tools.CustomTaskPane _CustomTaskPane;
        _CustomTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(_Control, _Title, _Window);

        // choix du docking possible. On empeche en horizontal
        _CustomTaskPane.DockPositionRestrict = Microsoft.Office.Core.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoHorizontal;

        // visibilité
        _CustomTaskPane.Visible = true;

Je me suis branché sur l’évènement de double click du contrôle WPF. Cela me permet de récupérer un objet de type Contact et d’exploiter ces données pour les insérer dans le document Word. Je vous met le code pour info sur l’utilisation du modèle objet de Word :

void rotator_OnDoubleClick(object sender, ContactDoubleClickEventArgs e)
        {
        if (e.Contact == null)
        return;
        string text = string.Format("{0} {1}\r\n{2}\r\n{3}\r\n{4}\r\n",
        e.Contact.Prenom,
        e.Contact.Nom,
        e.Contact.Societe,
        e.Contact.Adresse1,
        e.Contact.Adresse2
        );
        //creation d'une table
        Table tb = Globals.ThisAddIn.Application.Selection.Document.Tables.Add(
        Globals.ThisAddIn.Application.Selection.Range,
        1, 3, ref missing, ref missing);
        tb.Rows[1].Cells[3].Range.Text = text;

        //creation de l'image
        Bitmap high = new Bitmap(e.Contact.Image);
        Image bpm = high.GetThumbnailImage(320, 240, null, IntPtr.Zero);
        high.Dispose();
        bpm.Save(@"temp.jpg");
        bpm.Dispose();

        //insertion de l'image dans le tableau
        tb.Rows[1].Cells[1].Range.InlineShapes.AddPicture(@"temp.jpg", ref missing, ref missing, ref missing);
        }

Il ne reste plus qu’à exécuter le projet. Visual Studio lance Word et installe l’addin. Je click sur mon onglet puis sur le bouton. Le volet s’affiche à droite. Je peux double cliquer sur un des contacts, ça insère dans mon document l’image et l’adresse postale de ce contact:

image

Téléchargez le code source ici

Tagués avec :

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

Verifions que vous êtes un humain * Time limit is exhausted. Please reload CAPTCHA.