Ein Command-Modell für System.AddIn, Teil 2
Nachdem ich im ersten Teil bereits mein Command-Modell und dessen Integration in die Host-Anwendung beschrieben habe, soll es nun um die Add-In-Seite gehen.
Während der Aktivierung ruft die AddInHost-Komponente die InitializeCommands()-Methode des Add-In auf. Hierbei wird eine Instanz von ICommandContext übergeben, über die das Add-In Zugriff auf ICommandService und IUIContextService hat. Über diese Interfaces läuft im weiteren Verlauf die Kommunikation. Die folgende Abbildung zeigt den grundlegenden Ablauf.
Das Add-In muss nun zunächst die vom Host angebotene Command-Struktur ermitteln, um sich im Anschluss in diese integrieren zu können.
public override void InitializeCommands(ICommandContext context)
{
// CommandService und UICommandService ermitteln
ICommandService cmdSrv = context.CommandService;
IUICommandService cmdUISrv=context.UICommandService;
// File-Commands ermitteln
ICommand fileCmd = cmdSrv.GetCommand("Host.File");
IUICommand fileUICmd = cmdUISrv.GetUICommand(
fileCommand, UICommandType.MenuCommand);
// Toolbar ermitteln
IUICommand toolbarUICmd = cmdUISrv.GetMainToobar();
...
}
Hier werden die ICommand- und IUICommand-Objekte des File-Menüs, sowie die primäre Toolbar ermittelt. Daraufhin können neue Elemente eingefügt werden:
// "Neu"-Command erstellen
ICommand fileNewCmd = cmdSrv.CreateCommand(
"FirstAddIn.File.New",
fileCmd);
Hierbei werden ein eindeutiger Name, sowie das jeweils übergeordnete Command-Objekt angegeben. Dazu passend können nun entsprechende Menü- und Toolbar-UICommands erstellt werden:
// "Neu"-UICommand erstellen
IUICommand fileNewUICmd = UICmdSrv.CreateMenuItem(
fileNewCmd,
"&Neu",
fileUICmd,
0,
ToolStripItemDisplayStyle.ImageAndText,
UICmdSrv.GetIconArray(Properties.Resources.New));
In diesem Fall wird ein Menüelement erstellt und hierbei das zugehörige ICommand-Objekt, ein Anzeigetext, das übergeordnetes IUICommand-Objekt, ein Index, sowie der Darstellungsstil und ein Symbol angegeben. Da Bilder in Form von Byte-Arrays über die AppDomain-Grenze geschickt werden, müssen sie über die GetIconArray()-, bzw. GetImageArray()-Methode entsprechend konvertiert werden.
Darüber hinaus können zusätzliche Eigenschaften wie Visible, Checked oder ShortcutKeys festgelegt werden.
Die Erstellung von Toolbar-Elementen erfolgt analog, nur dass hierfür die CreateToolbar()-Methode aufzurufen ist. Darüber hinaus können mit der CreateSeparator()-Methode Separatorelemente für Menü und Toolbar erstellt werden.
Wurde ein Command auf Host-Seite aktiviert, so ruft der Host die NotifyCommandExecuted()-Methode des Add-In auf und übergibt hierbei die jeweilige ICommand-Instanz.
Das Add-In kann daraufhin beispielsweise seine Oberfläche anzeigen. Hierfür bietet die CommandContext-Klasse die ShowSurface()-Methode, welche als Parameter eine WindowProxy-Instanz übergeben bekommt (Details hier).
public override void NotifyCommandExecuted(ICommand command)
{
if (command == m_fileNewCommand)
{
m_surface = new Surface();
m_context.ShowSurface(new WindowProxy(m_surface));
}
}
Surface ist ein User Control, welches von AddInSurface ableitet und die Oberfläche des Add-In enthält. Die Einzelheiten dieser Komponente habe ich bereits hier beschrieben.
Die Sourcen inkl. Beispielanwendung gibt's hier.
3 Comments:
Kewl...
Ein Problem habe ich allerdings.
Wenn ich im AddInSurface
Form myForm = this.FindForm();
aufrufe, kriege ich nix.
Any idea?
By Anonym, at März 24, 2008 6:53 PM
Zudem habe ich bemerkt, dass die Pfeil-Tasten in der TextBox eines AddIns nicht funktionieren.
Woran mag das liegen?
By Anonym, at April 01, 2008 12:33 AM
Zu Problem 1:
Das Ermitteln der Form über FindForm() funktioniert nicht, da sich das Add-In-Control und die Form in zwei separaten AddDomains befinden. Eine Synchronisation macht auch nicht wirklich Sinn, da das Add-In über diesen Weg sonst die Kontrolle über den Host übernehmen könnte. Statt dessen sollte der Host die entsprechende Funktionalität über den Add-In-Contract bereitstellen.
Zu Problem 2:
Ich habe das Problem behoben und die aktuelle Version hier bereit gestellt (siehe auch aktuellen Blog Post).
By Jörg Neumann, at April 22, 2008 1:19 PM
Kommentar veröffentlichen
<< Home