head.WriteLine()

Donnerstag, Februar 01, 2007

Pimp my ElementHost!

Mit dem ElementHost kann man ja bekanntlich WPF-Content in Windows Forms hosten. Dies geht im Moment jedoch rein programmatisch - eine Windows Forms Designer-Integration existiert (zumindest auf den ersten Blick) nicht.

ElementHost ist von Control abgeleitet und lässt sich somit auf eine Form ziehen (nachdem man die Komponente zuvor in die Toolbox eingefügt hat). Das Erscheinungsbild ist jedoch zunächst äußerst ernüchternd:



Das Control erscheint nämlich nur im Component Tray. Für den Entwurf einer komplexen Oberfläche, die neben Windows Forms auch WPF-Controls enthalten soll, ist das jedoch nicht wirklich akzeptabel.

Ein Blick unter die Haube fördert jedoch zu Tage, dass dies nicht unbedingt eine Limitation des Controls ist, sondern vielmehr auf das Fehlen einer Designer-Assembly zurückzuführen ist. Ein Blick in die WindowsFormsIntegration.dll schafft Klarheit:

[..., Designer("WindowsFormsIntegration.Design.ElementHostDesigner, WindowsFormsIntegration.Design, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
public class ElementHost : Control
{
...
}

Demnach wird die Klasse ElementHostDesigner für die Entwurfszeitdarstellung verwendet. Das Problem ist nur, dass die zugehörige Assembly WindowsFormsIntegration.Design.dll nicht zum Lieferumfang von .NET 3.0 gehört. Da die hier angegebene Klasse somit nicht erstellt werden kann, verweigert der Windows Forms-Designer die Darstellung und verbannt die Komponente in den Tray.

Diesen Misstand können Sie jedoch sehr leicht durch eine Ableitung beheben:

[Designer("System.Windows.Forms.Design.ControlDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
public class ElementHostControl : System.Windows.Forms.Integration.ElementHost
{
...
}

Hierbei weisen Sie der Klasse über das Designer-Attribut einfach den im Framework enthaltenen ControlDesigner zu. Zur Integration des WPF-Contents verwenden Sie nun statt ElementHost das ElementHostControl.

Damit nun aber zur Entwurfszeit auch der zu hostende Content angezeigt wird, haben Sie zwei Möglichkeiten. Entweder Sie leiten von ElementHostControl ab und erstellen im Konstruktor den Visual Tree programmatisch oder Sie binden ein WPF-Control dynamisch. Hierzu könnten Sie der Klasse z.B. eine ControlType-Eigenschaft verpassen und in dessen Setter die angegebene Klasse per Reflection instanziieren. Das so erstellte Objekt weisen Sie schließlich der Child-Eigenschaft von ElementHost zu.

In der aktuellen Orcas CTP (wohlgemerkt die CTP von VS9 und nicht die WPF-Extensions für VS2005) existiert hingegen die ominöse WindowsFormsIntegration.Design.dll und liefert auch eine sehr nette Integration:




Hierbei ist es auch möglich, das entsprechende WPF-Control innerhalb des WinForms-Projekts zu erstellen, was zurzeit ebenfalls nicht funktioniert.

Scheinbar möchte sich MS wohl noch ein paar Features für Oracas aufheben. Für alle, die zurzeit mit VS2005 + WPF-Extensions arbeiten, bleibt leider nur der oben genannte Workaround.

1 Comments:

  • Thank you for the good writeup. It in fact was a amusement account it.
    Look advanced to more added agreeable from you!

    By the way, how can we communicate?

    By Anonymous Anonym, at März 25, 2018 9:53 PM  

Kommentar veröffentlichen

<< Home