[VSTO] Comment associer une action d'un bouton du ruban sous Outlook 2010 à une méthode ?

Verrouillé [VSTO] Comment associer une action d'un bouton du ruban sous Outlook 2010 à une méthode ?

  • lundi 1 août 2011 09:52
     
      A du code
    Bonjoir,

    Contexte :
    Je suis actuellement en train de réaliser un complément pour MS Outlook 2010 (pour une utilisation personnelle) avec Visual Studio 2010. Ce complément a pour but d'exécuter toutes les règles de tri de mail qui sont configurées. Je ne souhaite pas que les mails soient triés dès leur arrivée car mon téléphone WM6.5 (aussi synchronisé avec ma messagerie) n'est plus capable de lire un nouveau mail quand il a été déplacé dans un dossier (push Hotmail).

    Voici le code pour ceux que ça intéresse (je sais c'est du VB.Net, mais je suis trop flemmard pour du C#) :

     
    Public Sub BoutonRegles_Click()
        For Each rule As Outlook.Rule In Me.Application.Session.DefaultStore.GetRules()
            rule.Execute(True, Type.Missing, Type.Missing, Type.Missing)
        Next
    End Sub 
    


    Problématique 1 :
    Le complément est fonctionnel, mais je souhaiterais afficher un (gros) bouton relié à cette action. J'ai réussi à afficher un bouton miniature (voir capture), mais lorsque j'ajoute un bouton sur mon Ribbon créé pour l'occasion, je n'arrive pas à gérer l'évenement Click une fois que j'ai généré le Ribbon.vb/.xml. Dans le Ribbon.vb, je ne connais plus mon Button1 et même si je met la méthode définie dans l'action onClick du fichier XML, je ne rentre pas dedans. idem si elle est définie dans ThisAddIn.
    Je souhaite utiliser un 'gros' bouton car il peut être mis directement dans la barre d'accès rapide, alors que le bouton (comme j'ai réalisé avec la méthode AddBouton) n'est accessible dans la barre d'accès rapide que par un sous-menu.

    Ma Classe ThisAddIn :
    Imports Microsoft.Office.Core
    
    Public Class ThisAddIn
    
        Private menuBar As Office.CommandBar
        Private boutonRegles As Office.CommandBarButton
    
        Private Sub ThisAddIn_Startup() Handles Me.Startup
            AddButton()
        End Sub
    
        Protected Overrides Function CreateRibbonExtensibilityObject() As Microsoft.Office.Core.IRibbonExtensibility
            Return New Ribbon()
        End Function
    
        Private Sub AddButton()
            Try
                menuBar = Me.Application.ActiveExplorer().CommandBars.ActiveMenuBar
                boutonRegles = menuBar.Controls.Add( _
                        Office.MsoControlType.msoControlButton, _
                        Before:=1, Temporary:=False)
    
                With boutonRegles
                    .Style = Office.MsoButtonStyle.msoButtonIconAndCaptionBelow
                    .Caption = "Exécuter toutes les règles"
                    .FaceId = 65
                    .Tag = "c123"
                End With
                AddHandler boutonRegles.Click, AddressOf BoutonRegles_Click
    
            Catch Ex As Exception
                MsgBox(Ex.Message)
            End Try
        End Sub
    
        Public Sub BoutonRegles_Click()
            For Each rule As Outlook.Rule In Me.Application.Session.DefaultStore.GetRules()
                rule.Execute(True, Type.Missing, Type.Missing, Type.Missing)
            Next
        End Sub
    
        Public Sub BoutonRegles_Click(ByVal control As IRibbonControl, ByVal pressed As Boolean)
            MsgBox("ThisAddIn")
        End Sub
    
        Private Sub ThisAddIn_Shutdown() Handles Me.Shutdown
    
        End Sub
    
    End Class
    

    Mon Ribbon.xml :
    <?xml version="1.0" encoding="UTF-8"?>
    <customUI onLoad="Ribbon_Load" xmlns="http://schemas.microsoft.com/office/2006/01/customui">
        <ribbon>
            <tabs>
                <tab idMso="TabAddIns">
                    <group id="matll" label="matll">
                        <button id="Button1" label="Exécuter Regles" size="large" onAction="ThisAddIn.BoutonRegles_Click" />
                    </group>
                </tab>
            </tabs>
        </ribbon>
    </customUI>
    
    J'ai essayé diverses méthodes, mais aucune ne fonctionne (pas d'action au click).

    J'ai vu dans d'autres tutos pour Access, Excel ou Word qu'il faut que je réalise ma méthode CallBack (attribut onAction en ce qui me concerne). La signature est la suivante : sub OnAction(control as IRibbonControl)

    2 question à propos de cette méthode :
    1. La méthode doit-elle obligatoirement s'appeler OnAction ? (ça m'étonnerait car sinon un seul bouton), le nom est celui donné dans onAction du XML. J'ai aussi vu sur certains tutos que le nom de la méthode (dans le fichier XML) était préfixé par le nom de la classe.
    2. Où doit être implémentée cette méthode ? dans mon ThisAddIn, dans Ribbon.vb ou dans Ribbon1.vb ?
    Capture
    C'est mon premier complément pour Office, mais j'ai un peu d'expérience avec le VB.Net
    Merci d'avance,

    @+
    Mat

Toutes les réponses

  • lundi 1 août 2011 17:33
     
     Traitée A du code

    Salut,

    J'ai finalement refais mon complément en C# et ça a fonctionné du premier coup, rien à faire du coté de l'AddIn pour que l'action du bouton soit prise en compte.

    Je me suis inspiré de ce tuto : http://blogs.msdn.com/b/mcsuksoldev/...rt-1-of-2.aspx

    Ma classe ThisAddIn :

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml.Linq;
    using Outlook = Microsoft.Office.Interop.Outlook;
    using Office = Microsoft.Office.Core;
    using Microsoft.VisualStudio.Tools.Applications.Runtime;
    
    namespace OutlookAddIn2
    {
    
     public partial class ThisAddIn {
    
    
      private void ThisAddIn_Startup(object sender, System.EventArgs e) {
       
      }
    
    
      private void ThisAddIn_Shutdown(object sender, System.EventArgs e) {
      }
    
      #region VSTO generated code
    
      /// <summary>
      /// Required method for Designer support - do not modify
      /// the contents of this method with the code editor.
      /// </summary>
      private void InternalStartup()
      {
       this.Startup += new System.EventHandler(ThisAddIn_Startup);
       this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
      }
      
      #endregion
     }
    }
    

     

    Ma classe Ribbon1.cs :

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Office.Tools.Ribbon;
    using Outlook = Microsoft.Office.Interop.Outlook;
    
    namespace OutlookAddIn2
    {
     public partial class Ribbon1
     {
      private void Ribbon1_Load(object sender, RibbonUIEventArgs e) {
    
      }
    
      private void button1_Click(object sender, RibbonControlEventArgs e) {
       Outlook.Application outlookApplication = new Outlook.Application();
       foreach (Microsoft.Office.Interop.Outlook.Rule rule in outlookApplication .Session.DefaultStore.GetRules())
       {
        rule.Execute(true);
       }
      }
     }
    }
    

     

    Et le fichier Ribbon1.Designer.cs associé :

     

    namespace OutlookAddIn2
    {
     partial class Ribbon1 : Microsoft.Office.Tools.Ribbon.RibbonBase
     {
      /// <summary>
      /// Variable nécessaire au concepteur.
      /// </summary>
      private System.ComponentModel.IContainer components = null;
    
      public Ribbon1()
       : base(Globals.Factory.GetRibbonFactory())
      {
       InitializeComponent();
      }
    
      /// <summary> 
      /// Nettoyage des ressources utilisées.
      /// </summary>
      /// <param name="disposing">true si les ressources managées doivent être supprimées*; sinon, false.</param>
      protected override void Dispose(bool disposing)
      {
       if (disposing && (components != null))
       {
        components.Dispose();
       }
       base.Dispose(disposing);
      }
    
      #region Code généré par le Concepteur de composants
    
      /// <summary>
      /// Méthode requise pour la prise en charge du concepteur - ne modifiez pas
      /// le contenu de cette méthode avec l'éditeur de code.
      /// </summary>
      private void InitializeComponent()
      {
       this.tabMatll = this.Factory.CreateRibbonTab();
       this.group1 = this.Factory.CreateRibbonGroup();
       this.button1 = this.Factory.CreateRibbonButton();
       this.tabMatll.SuspendLayout();
       this.group1.SuspendLayout();
       // 
       // tabMatll
       // 
       this.tabMatll.Groups.Add(this.group1);
       this.tabMatll.Label = "Matll";
       this.tabMatll.Name = "tabMatll";
       // 
       // group1
       // 
       this.group1.Items.Add(this.button1);
       this.group1.Label = "Règles";
       this.group1.Name = "group1";
       // 
       // button1
       // 
       this.button1.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
       this.button1.Image = global::OutlookAddIn2.Properties.Resources.CMS_EnCours;
       this.button1.Label = "Exécuter toutes les règles";
       this.button1.Name = "button1";
       this.button1.ShowImage = true;
       this.button1.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.button1_Click);
       // 
       // Ribbon1
       // 
       this.Name = "Ribbon1";
       this.RibbonType = "Microsoft.Outlook.Explorer";
       this.Tabs.Add(this.tabMatll);
       this.Load += new Microsoft.Office.Tools.Ribbon.RibbonUIEventHandler(this.Ribbon1_Load);
       this.tabMatll.ResumeLayout(false);
       this.tabMatll.PerformLayout();
       this.group1.ResumeLayout(false);
       this.group1.PerformLayout();
    
      }
    
      #endregion
    
      internal Microsoft.Office.Tools.Ribbon.RibbonTab tabMatll;
      internal Microsoft.Office.Tools.Ribbon.RibbonGroup group1;
      internal Microsoft.Office.Tools.Ribbon.RibbonButton button1;
     }
    
     partial class ThisRibbonCollection
     {
      internal Ribbon1 Ribbon1
      {
       get { return this.GetRibbon<Ribbon1>(); }
      }
     }
    }
    

     


    Et concernant l'image, cela fonctionne aussi sans problème avec C#. Etrange...

     

    @+

    Mat

    EDIT : en ne refaisant que les actions nécessaires (comme pour le C#), le projet en VB fonctionne. nullement besoin d'exporter le Ruban en XML finalement, désolé du dérangement.
    • Marqué comme réponse matll42 lundi 1 août 2011 17:33
    • Modifié matll42 lundi 1 août 2011 17:40 Re-test en VB fonctionnel
    •