12.8 WPF und Windows Forms
Sie können die Vorteile der WPF nutzen, ohne all Ihre Windows Forms-Anwendungen vollständig neu zu programmieren. Es ist leicht möglich, WPF-Elemente in eine Windows Forms-Anwendung einzubetten.
Anders herum gibt es in der WPF noch nicht alle Elemente, die Sie aus Windows Forms kennen. Sie können aber eine WPF-Anwendung mit Elementen aus Windows Forms erweitern.
12.8.1 Windows Forms in WPF
Nun wird ein Steuerelement aus Windows Forms in ein Projekt vom Typ WPF-Anwendung eingesetzt. Zur Arbeit mit Windows Forms müssen Sie dem WPF-Projekt einen Verweis auf die .NET-Komponente System.Windows.Forms hinzufügen. Daraus muss der gleichnamige Namespace im XAML-Code zur Verfügung gestellt werden. Außerdem wird für die Nutzung im Programmcode die .NET-Komponente WindowsFormsIntegration benötigt.
Anschließend können Sie im XAML-Code ein WPF-Element des Typs WindowsFormsHost einsetzen. Dabei handelt es sich um einen Container für Windows Forms-Elemente. Die Eigenschaft Child enthält ein Steuerelement aus Windows Forms.
Im nachfolgenden WPF-Projekt WPFFormsInside werden zwei Buttons dargestellt: ein WPF- und ein Windows Forms-Button, siehe Abbildung 12.9.
Abbildung 12.9 Windows Forms-Button in WPF-Anwendung
Der XAML-Code:
<Window x:Class=... xmlns="http://..." xmlns:x="http://..."
xmlns:wfalt="clr-namespace:System.Windows.Forms;
assembly=System.Windows.Forms" ...>
<Canvas>
<Button Width="150" Margin="3" Click="WPF_Click">
Hallo WPF</Button>
<WindowsFormsHost x:Name="wfh" Canvas.Top="30"
Width="150" Height="23" Margin="3"
Background="LightGray" Foreground="Black">
<wfalt:Button Click="WFO_Click"
Text="Hallo Windows Forms" />
</WindowsFormsHost>
</Canvas>
</Window>
Listing 12.17 Projekt »WPFFormsInside«, XAML-Code
Der Namespace System.Windows.Forms aus der gleichnamigen .NET-Komponente bekommt hier den lokalen Namen wfalt. Damit ist es möglich, einen Windows Forms-Button mit seinen spezifischen Eigenschaften (zum Beispiel: Text) zu erzeugen. Die Click-Ereignisse der beiden Buttons führen zu folgenden Ereignismethoden:
Class MainWindow
Private Sub WPF_Click(sender As Object,
e As RoutedEventArgs)
MessageBox.Show("Hallo WPF")
End Sub
Private Sub WFO_Click(sender As Object, e As EventArgs)
MessageBox.Show(wfh.Child.Text)
End Sub
End Class
Listing 12.18 Projekt »WPFFormsInside«, Programmcode
Die Eigenschaft Child des WindowsFormsHost beinhaltet den Windows Forms-Button. Dessen Eigenschaft Text wird ausgegeben.
12.8.2 WPF in Windows Forms
In diesem Abschnitt werden Steuerelemente aus der WPF in einem Projekt vom Typ Windows Forms-Anwendung eingesetzt. Zur Arbeit mit der WPF müssen Sie dem jeweiligen Windows Forms-Projekt folgende Verweise auf .NET-Komponenten hinzufügen: PresentationCore, PresentationFramework, WindowsBase, WindowsFormsIntegration und System.Xaml.
In einer Windows Forms-Anwendung kann ein Steuerelement vom Typ ElementHost ein WPF-Element vom Typ UIElement enthalten. Dies kann ein Steuerelement oder auch ein Layout-Objekt sein.
Im nachfolgenden Projekt WPFInForms werden ein Windows Forms-Button, ein WPF-Button und ein WPF-Expander mit drei WPF-TextBlock-Objekten eingesetzt, siehe Abbildung 12.10. Expander- und TextBlock-Objekte stehen bekanntlich unter Windows Forms ohne die WPF nicht zur Verfügung.
Abbildung 12.10 Windows Forms-Anwendung mit WPF-Elementen
Es wird ein neues Projekt vom Typ Windows Forms-Anwendung erzeugt. Das Formular bekommt die Größe 350 mal 200. Anschließend werden aus der Toolbox ein Button und zwei Steuerelemente vom Typ ElementHost hinzugefügt, aus der Kategorie WPF-Interoperabilität. Der Button bekommt den Namen WFO_Button und die Größe 160 mal 23. Die beiden ElementHost-Objekte bekommen die Namen ehost1 und ehost2 und die Größen 160 mal 23 und 160 mal 80. Das Ergebnis sehen Sie in Abbildung 12.11 im Entwurfsmodus.
Abbildung 12.11 Windows Forms-Anwendung im Entwurf
Es folgt der Code zum Formular in der Datei Form1.vb:
Imports System.Windows.Controls
Public Class Form1
Sub New()
InitializeComponent()
Dim nb As System.Windows.Controls.Button = New Button
nb.Content = "WPF Button"
AddHandler nb.Click, AddressOf klicken
ehost1.Child = nb
Dim sp As StackPanel = New StackPanel
Dim i As Integer
For i = 1 To 3
Dim tb As TextBlock = New TextBlock
tb.Text = "Inhalt " & i
sp.Children.Add(tb)
Next
Dim ep As Expander = New Expander
ep.Header = "WPF Expander"
ep.Content = sp
ehost2.Child = ep
End Sub
Private Sub klicken(sender As Object,
e As System.Windows.RoutedEventArgs)
System.Windows.Forms.MessageBox.Show(sender.Content)
End Sub
Private Sub WFO_Button_Click(sender As System.Object,
e As System.EventArgs) Handles WFO_Button.Click
System.Windows.Forms.MessageBox.Show(
"Windows Forms Button")
End Sub
End Class
Listing 12.19 Projekt »WPFInForms«, Programmcode
Einige Klassennamen müssen mit dem vollständigen Namen des jeweiligen Namespaces angegeben werden. Ansonsten besteht ein Konflikt aufgrund der gleichen Klassennamen aus verschiedenen Namespaces.
Es wird ein WPF-Button erzeugt. Dem Button werden ein EventHandler und eine Ereignismethode zugeordnet. Der Button wird der Eigenschaft Child des ersten ElementHost-Objekts zugeordnet.
Außerdem wird ein StackPanel mit drei TextBlock-Objekten erzeugt. Dieses StackPanel wird der Inhalt eines Expander-Objekts. Das Expander-Objekt wird der Eigenschaft Child des zweiten ElementHost-Objekts zugeordnet.
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.