Home > Programmierung > Registerkarte zum Outlook Optionen-Dialog hinzufügen

Registerkarte zum Outlook Optionen-Dialog hinzufügen

Nachdem ich jetzt ca. 1 Std. gebraucht habe um herauszufinden wie es geht beschreibe ich das einfache Verfahren.


Zunächst fügt man seinem Outlook Add-In Projekt ein Benutzersteuerelement hinzu welches die Registerkarte die man später im Optionen-Dialog haben möchte darstellt. Ich habe dieses in diesem Beispiel ctlOptionen genannt. Wichtig ist, dass man die erste Zeile (” … ComVisible(true)”) hinzufügt, da das Steuerelement ansonsten nicht als ActiveX COM Element sichtbar ist. (Dies war übrigens auch mein großes Problem, aber da muss man erst einmal ohne Fehlermeldung drauf kommen… Hier habe ich endlich die Lösung gefunden.)

Ausserdem habe ich hier eine Methode gefunden um das PropertyPageSite Objekt zu bekommen welches man braucht um das Optionen Formular durch aufrufen des OnStatusChange Ereignisses darüber zu benachrichtigen, dass sich etwas in den Optionen geändert hat. Es sollte beachtet werden, dass in diesem Beispiel beim Ändern von Einstellungen die isDirty-Variable über die entsprechende Eigenschaft auf true gesetzt werden muss, damit das Optionen-Formular benachrichtigt wird.

[System.Runtime.InteropServices.ComVisible(true)]
public partial class ctlOptionen : UserControl,
    Microsoft.Office.Interop.Outlook.PropertyPage
{
    private bool isDirty = false;
    private Microsoft.Office.Interop.Outlook.PropertyPageSite site;

    public ctlOptionen()
    {
        InitializeComponent();
    }

    #region PropertyPageSite Objekt holen
    /// <summary>
    /// Hier wird die entpsrechende PropertyPageSite geholt, bei der das OnStatusChange()
    /// Ereignis ausgelöst wird um das Optionen-Formular zu benachrichtigen, dass etwas
    /// geändert wurde.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void ctlOptionen_Load(object sender, EventArgs e)
    {
        Type type = typeof(UserControl);
        Type oleType = type.Assembly.GetType(
            "System.Windows.Forms.UnsafeNativeMethods+IOleObject");
        if (oleType == null) throw new InvalidOperationException(
            "Could not get 'System.Windows.Forms.UnsafeNativeMethods+IOleObject'.");

        System.Reflection.MethodInfo method =
            oleType.GetMethod("GetClientSite");
        if (method == null) throw new InvalidOperationException(
            "Could not get method 'IOleObject.GetClientSite'.");

        site = method.Invoke(this, null) as
            Microsoft.Office.Interop.Outlook.PropertyPageSite;
    }
    #endregion

    #region PropertyPage Member

    /// <summary>
    /// Wird aufgerufen wenn die gemachten Änderungen gespeichert werden sollen 
    /// (Klick auf OK bzw. Übernehmen)
    /// </summary>
    public void Apply()
    {
    }
    /// <summary>
    /// Gibt true zurück, wenn die Optionen der Seite sich geändert haben. 
    /// Wird von Outlook benutzt um zu entscheiden ob der Übernehmen-Button aktiviert ist.
    /// Beim setzen wird hier das Optionen-Formular benachrichtigt, dass sich etwas 
    /// geändert hat.
    /// </summary>
    [Browsable(false)]
    public bool Dirty
    {
        get { return isDirty; }
        set
        {
            if (isDirty != value)
            {
                isDirty = value;
                if (site != null) site.OnStatusChange();
            }
        }
    }

    /// <summary>
    /// Hier kann man eine Hilfedatei angeben die mit dieser Seite verknüpft ist.
    /// </summary>
    /// <param name="HelpFile"></param>
    /// <param name="HelpContext"></param>
    public void GetPageInfo(ref string HelpFile, ref int HelpContext)
    {
    }

    #endregion
}

Als nächstes fügt man einen Ereignishandler (Das ist tatsächlich die deutsche Übersetzung laut MSDN…) für das OptionPagesAdd-Event hinzu. Dieses Ereignis wird jedes mal angestoßen wenn der Optionen-Dialog geöffnet wird. Dieser kann gut in der ThisAddIn_Startup Methode der ThisAddIn-Klasse untergebracht werden.

Application.OptionsPagesAdd += new Microsoft.Office.Interop.Outlook
    .ApplicationEvents_11_OptionsPagesAddEventHandler
        (Application_OptionsPagesAdd);

Dementsprechend wird auch die Methode erstellt welche dann nichts anderes tut als die Registerkarte hinzuzufügen.

void Application_OptionsPagesAdd
    (Microsoft.Office.Interop.Outlook.PropertyPages Pages)
{
    Pages.Add(new ctlOptionen(), "Meine Optionen");
}
  1. 14. Februar 2010, 22:27 | #1

    Moin,
    erstmal danke für den Beitrag. Hat mir ne ganze Stunde Suchen und Probieren erspart ;) .

    Aber vielleicht noch eine kurze Frage: Was sagt die “Best Practice” zum Thema Speichern der Informationen die in der Option Page eingetragen werden?

    Haste da nen Tipp, wie das am Besten gemacht werden kann? Soll heißen z. B. die Informationen in einer Konfigurationsdatei auf der Platte ablegen und beim Starten von Outlook auslesen? Oder gibts da ne komfortablere Methode?

    Vielen Dank im Voraus.

    Johnny

  2. 14. Februar 2010, 22:32 | #2

    Hi, ich nochmal.

    Abgesehen von dem Danke, vergiss den Rest. Is doch logisch. Kann ja die Properties des Add-Ins verwenden.

    Manchmal sitzt man halt doch auf dem Schlauch :) .

    Bis neulich

    Johnny

  3. Denis
    14. Februar 2010, 23:39 | #3

    Kein Problem – wäre jetzt auch meine Antwort gewesen…

  4. Sebastian
    21. Januar 2011, 11:20 | #4

    Hallo,
    das Hinzufügen der Registerkarte funktioniert soweit und ich kann meine Settings auch speichern (z.Zt. in der Registry). Rufe ich die Registerkarte allerdings erneut auf, wird die “Übernehmen”-Schaltfläche nie mehr aktiv, weil das “site”-Objekt stets null ist. Klingt logisch, da ich ja bereits eine Registerkarte eingefügt habe. Aber wie komme ich an das bereits erstellte site-Objekt, um daran wieder die “Dirty”-Methode aufzurufen?
    Danke und Gruß
    Sebastian

  5. Denis
    21. Januar 2011, 11:39 | #5

    Hi.
    ich muss jetzt ehrlich gesagt gestehen, dass ich nicht mehr wirklich im Thema drin stecke. Aber auf Anhieb würde ich sagen, dass Du am besten die geänderten Einstellungen in deinem Add-In speicherst und beim Laden der Registerkarte auch isDirty aufrufst, falls Du in deinem AddIn ungespeicherte Einstellungen hast.

  6. Sebastian
    21. Januar 2011, 14:43 | #6

    Hallo,
    ich hab es nun hinbekommen. Problem war, dass ich die Werte aus der Registry in die Textfelder geladen habe bevor ich das site-Objekt erstellt hatte. Beim Beschreiben der Textfelder wurde über die onTextChanged-Events die Dirty-Methode aufgerufen und da das site-Objekt noch nicht vorhanden war, wurde site.onStatusChanged() nicht aufgerufen. Lösung: über das Keypress-Event “isDirty” auf “true” setzen.
    Danke und Gruß
    Sebastian

  7. Denis
    23. Januar 2011, 16:46 | #7

    Super – danke für den Hinweis!

  1. Bisher keine Trackbacks