SmartTags für alle


Visual Studio 2008 / .NET 3.5 Service Pack 1 brachte auch für VSTO ein paar Updates. Eines zählt zu meinen Lieblings-Features: SmartTags. Bisher waren diese nur für dokumentzentrische Anwendungen verfügbar, also an ein bestimmtes Dokument oder eine Vorlage gebunden. Klar, diese Einschränkung hatte auch seine Vorteile. So konnte man viel aggressiver an die Erkennung von Mustern oder Begriffen (sog. Terms) gehen, da der Gültigkeitsbereich des SmartTags sehr stark eingeschränkt (nämlich das eine Dokument) war.


Nun sind diese Objekte und Klassen auch in einem zentralen Add-In verfügbar. Hier ein Beispiel, welches eine Liste von Begriffen und darüber einen SmartTag mit einer Action definiert. Als Action dient eine einfache Web-Suche auf Wikipedia.


 


using Word = Microsoft.Office.Interop.Word;
using Office = Microsoft.Office.Core;
using VSTO = Microsoft.Office.Tools.Word;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace AppLevelSmartTag4AllDocs
{
public partial class ThisAddIn
{
private VSTO.SmartTag myTermsSmartTag = null;
private string[] terms = { "Luke", "Leia", "Han", "Anakin", "Jacen", "Jaina", "Vader", "Wedge" };
private VSTO.Action acSearchWikipedia;

private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
myTermsSmartTag
= new VSTO.SmartTag("SmartTags.jensha.net/StarWars#CharacterSample", "Star Wars Character Sample");
foreach (string t in terms)
myTermsSmartTag.Terms.Add(t);

acSearchWikipedia = new VSTO.Action("Star Wars///Get Info from Wikipedia");
acSearchWikipedia.Click
+= new Microsoft.Office.Tools.Word.ActionClickEventHandler(acSearchWikipedia_Click);

myTermsSmartTag.Actions = new VSTO.Action[] { acSearchWikipedia };

VstoSmartTags.Add(myTermsSmartTag);
}

void acSearchWikipedia_Click(object sender, Microsoft.Office.Tools.Word.ActionEventArgs e)
{
string searchText = "%22Star Wars%22 %22" + e.Text + "%22";
System.Diagnostics.Process.Start(
"http://en.wikipedia.org/wiki/Special:Search?search=" + searchText);
}
}
}


Der so definierte SmartTag gilt nun für alle geöffneten und noch zu öffnenden bzw. neuen Dokumente. Aber es geht noch besser. Was ist, wenn ich den Gültikeitsbereich einschränken will? Wenn nur bestimmte Dokumente den SmartTag bekommen sollen? Auch das läßt sich bewältigen. Über neue Extensions (Microsoft.Office.Tools.xxxx.Extension) kann die benötigte Funktionalität - nämlich der Zugriff auf die lokalen Objekte des Dokuments - erreicht werden. Die Methode heißt GetVstoObject() und liefert hier den Zugriff auf die SmartTag Collection.


Da der SmartTag nun nicht mehr automatisch alle Dokumente umfaßt, müssen wir uns selbst um das Hinzufügen neuer Dokumente kümmern. Also jedes Mal, wenn ein Dokument geöffnet oder neu angelegt wird (Office Events abfangen), prüfen wir, ob das Dokument in unser Muster paßt (hier nicht implementiert) und fügen bei positiver Überprüfung den SmartTag der SmartTag Collection des Dokuments hinzu.


 


using Microsoft.Office.Tools.Word.Extensions;
...

namespace AppLevelSmartTag4AllDocs
{
public partial class ThisAddIn
{
...

private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
foreach (Word.Document doc in this.Application.Documents)
AttachSmartTag(doc);

this.Application.DocumentOpen +=
new Word.ApplicationEvents4_DocumentOpenEventHandler(WordApp_DocumentOpen);
((Word.ApplicationEvents4_Event)Application).NewDocument
+=
new Word.ApplicationEvents4_NewDocumentEventHandler(WordApp_NewDocument);
}

void WordApp_NewDocument(Microsoft.Office.Interop.Word.Document doc)
{
AttachSmartTag(doc);
}

void WordApp_DocumentOpen(Microsoft.Office.Interop.Word.Document doc)
{
AttachSmartTag(doc);
}

private void AttachSmartTag(Word.Document doc)
{
if (myTermsSmartTag == null)
{
myTermsSmartTag
= new VSTO.SmartTag("SmartTags.jensha.net/StarWars#CharacterSample", "Star Wars Character Sample");
foreach (string t in terms)
{
myTermsSmartTag.Terms.Add(t);
}

acSearchWikipedia = new VSTO.Action("Star Wars///Get Info from Wikipedia");
acSearchWikipedia.Click
+= new Microsoft.Office.Tools.Word.ActionClickEventHandler(acSearchWikipedia_Click);

myTermsSmartTag.Actions = new VSTO.Action[] { acSearchWikipedia };
}

doc.GetVstoObject().VstoSmartTags.Add(myTermsSmartTag);
}


Im Beispiel wurde mit der Terms Liste gearbeitet, die allerdings nur aus einem Wort bestehende Begriffe erkennt, da der in Word eingebaute Tokenizer den Text in entsprechende Tokens zerlegt. Werden Begriffe benötigt, die aus mehreren Worten bestehen oder einem bestimmten Muster unterliegen, so kann mit Regular Expressions gearbeitet werden.


GetVstoObject() hat noch andere Vorteile: Man kann so auf die im Dokument eingebetteten Objekte (HostItems, wie z.B. ein ListObject in Excel) zugreifen.

Skip to main content