Exemplarische Vorgehensweise: Anordnen von Windows Forms-Steuerelementen in WPF
In dieser exemplarischen Vorgehensweise erfahren Sie, wie Sie in einer Hybridanwendung WPF-Layoutfunktionen verwenden und Windows Forms-Steuerelemente anordnen.
In dieser exemplarischen Vorgehensweise werden u. a. folgende Aufgaben veranschaulicht:
- Erstellen des Projekts
- Verwenden der Standardlayouteinstellungen.
- Anpassen der Größe an Inhalt.
- Verwenden der absoluten Positionierung.
- Explizites Angeben der Größe.
- Festlegen der Layouteigenschaften.
- Grundlegendes zu Einschränkungen der Z-Reihenfolge.
- Andocken.
- Einstellen der Sichtbarkeit.
- Hosten eines Steuerelements, das nicht gestreckt wird.
- Skalieren.
- Drehen.
- Einstellen von Abständen und Rändern.
- Verwenden von dynamischen Layoutcontainern.
Eine vollständige Codeauflistung der Aufgaben in dieser exemplarischen Vorgehensweise finden Sie unter Beispiel für das Anordnen von Windows Forms-Steuerelementen in WPF.
Anschließend werden Sie verstehen, welche Rolle Windows Forms-Layoutfunktionen bei WPF-basierten Anwendungen spielen.
Voraussetzungen
Für diese exemplarische Vorgehensweise benötigen Sie Visual Studio.
Erstellen des Projekts
Führen Sie die folgenden Schritte aus, um das Projekt zu erstellen und einzurichten:
Erstellen Sie ein WPF-Anwendungsprojekt mit dem Namen
WpfLayoutHostingWf
.Fügen Sie im Projektmappen-Explorer Verweise auf die folgenden Assemblys hinzu:
- WindowsFormsIntegration
- System.Windows.Forms
- System.Drawing
Doppelklicken Sie auf MainWindow.xaml, um die Datei in der XAML-Ansicht zu öffnen.
Fügen Sie im Window-Element die folgende Windows Forms-Namespacezuordnung hinzu.
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
Setzen Sie im Grid-Element die ShowGridLines-Eigenschaft auf
true
und definieren Sie fünf Zeilen und drei Spalten.<Grid ShowGridLines="true"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions>
Verwenden der Standardlayouteinstellungen
Standardmäßig bearbeitet das WindowsFormsHost-Element das Layout für das gehostete Windows Forms-Steuerelement.
Führen Sie die folgenden Schritte aus, um Standardlayouteinstellungen zu verwenden:
Kopieren Sie den folgenden XAML-Code in das Grid-Element.
<!-- Default layout. --> <Canvas Grid.Row="0" Grid.Column="0"> <WindowsFormsHost Background="Yellow"> <wf:Button Text="Windows Forms control" FlatStyle="Flat"/> </WindowsFormsHost> </Canvas>
Drücken Sie F5, um die Anwendung zu erstellen und auszuführen. Das Windows Forms-Steuerelement System.Windows.Forms.Button wird in der Canvas angezeigt. Die Größe des gehosteten Steuerelements basiert auf dessen Inhalt, und die Größe des WindowsFormsHost-Elements wird an das gehostete Steuerelement angepasst.
Anpassen der Größe an Inhalt
Das WindowsFormsHost-Element stellt sicher, dass das gehostete Steuerelement die richtige Größe hat, um seinen Inhalt korrekt anzuzeigen.
Führen Sie die folgenden Schritte aus, um die Größe an die Inhalte anzupassen:
Kopieren Sie den folgenden XAML-Code in das Grid-Element.
<!-- Sizing to content. --> <Canvas Grid.Row="1" Grid.Column="0"> <WindowsFormsHost Background="Orange"> <wf:Button Text="Windows Forms control with more content" FlatStyle="Flat"/> </WindowsFormsHost> </Canvas> <Canvas Grid.Row="2" Grid.Column="0"> <WindowsFormsHost FontSize="24" Background="Yellow"> <wf:Button Text="Windows Forms control" FlatStyle="Flat"/> </WindowsFormsHost> </Canvas>
Drücken Sie F5, um die Anwendung zu erstellen und auszuführen. Die Größe der zwei neuen Schaltflächen-Steuerelemente wird an die ordnungsgemäße Darstellung der längeren Textzeichenfolge und des größeren Schriftgrads angepasst, und die Größe der WindowsFormsHost-Elemente wird an die gehosteten Steuerelemente angepasst.
Verwenden der absoluten Positionierung
Sie können die absolute Positionierung verwenden, um das WindowsFormsHost-Element an einer beliebigen Stelle in der Benutzeroberfläche zu platzieren.
Führen Sie die folgenden Schritte aus, um die absolute Positionierung zu verwenden:
Kopieren Sie den folgenden XAML-Code in das Grid-Element.
<!-- Absolute positioning. --> <Canvas Grid.Row="3" Grid.Column="0"> <WindowsFormsHost Canvas.Top="20" Canvas.Left="20" Background="Yellow"> <wf:Button Text="Windows Forms control with absolute positioning" FlatStyle="Flat"/> </WindowsFormsHost> </Canvas>
Drücken Sie F5, um die Anwendung zu erstellen und auszuführen. Das WindowsFormsHost-Element wird 20 Pixel vom oberen Rand der Rasterzelle und 20 Pixel vom linken Rand platziert.
Explizites Angeben der Größe
Sie können die Größe des WindowsFormsHost-Elements mithilfe der Eigenschaften Width and Height angeben.
Führen Sie die folgenden Schritte aus, um die Größe explizit anzugeben:
Kopieren Sie den folgenden XAML-Code in das Grid-Element.
<!-- Explicit sizing. --> <Canvas Grid.Row="4" Grid.Column="0"> <WindowsFormsHost Width="50" Height="70" Background="Yellow"> <wf:Button Text="Windows Forms control" FlatStyle="Flat"/> </WindowsFormsHost> </Canvas>
Drücken Sie F5, um die Anwendung zu erstellen und auszuführen. Das WindowsFormsHost-Element wird auf eine Größe von 50 x 70 Pixel (Breite x Höhe) festgelegt und ist damit kleiner als die Standardlayouteinstellungen. Der Inhalt des Windows Forms-Steuerelements wird entsprechend neu angeordnet.
Festlegen der Layouteigenschaften
Layoutbezogenene Eigenschaften sollten immer mithilfe der Eigenschaften des WindowsFormsHost-Elements für das gehostete Steuerelement festgelegt werden. Das Festlegen der Layouteigenschaften direkt für das gehostete Steuerelement führt zu unbeabsichtigten Ergebnissen.
Das Festlegen von layoutbezogenen Eigenschaften für das gehostete Steuerelement in XAML hat keine Auswirkungen.
Führen Sie die folgenden Schritte aus, um die Auswirkungen der festgelegten Eigenschaften auf das gehostete Steuerelement zu sehen:
Kopieren Sie den folgenden XAML-Code in das Grid-Element.
<!-- Setting hosted control properties directly. --> <Canvas Grid.Row="0" Grid.Column="1"> <WindowsFormsHost Width="160" Height="50" Background="Yellow"> <wf:Button Name="button1" Click="button1_Click" Text="Click me" FlatStyle="Flat" BackColor="Green"/> </WindowsFormsHost> </Canvas>
Doppelklicken Sie im Projektmappen-Explorer auf MainWindow.xaml.vb oder MainWindow.xaml.cs, um sie im Code-Editor zu öffnen.
Kopieren Sie den folgenden Code in die Definition der
MainWindow
-Klasse:private void button1_Click(object sender, EventArgs e ) { System.Windows.Forms.Button b = sender as System.Windows.Forms.Button; b.Top = 20; b.Left = 20; }
Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs) Dim b As System.Windows.Forms.Button = sender b.Top = 20 b.Left = 20 End Sub
Drücken Sie F5, um die Anwendung zu erstellen und auszuführen.
Klicken Sie auf die Schaltfläche Hier klicken. Der
button1_Click
-Ereignishandler legt die Eigenschaften Top und Left für das gehostete Steuerelement fest. Dies bewirkt, dass das gehostete Steuerelement innerhalb des WindowsFormsHost-Elements neu positioniert wird. Der Host behält den gleichen Bildschirmbereich bei, jedoch wird das gehostete Steuerelement abgeschnitten. Stattdessen sollte das gehostete Steuerelement immer das WindowsFormsHost-Element ausfüllen.
Grundlegendes zu Einschränkungen der Z-Reihenfolge
Sichtbare WindowsFormsHost-Elemente werden immer über anderen WPF-Elementen gezeichnet und sind von der Z-Reihenfolge unbeeinflusst. Um dieses Verhalten der Z-Reihenfolge zu sehen, führen Sie die folgenden Schritte aus:
Kopieren Sie den folgenden XAML-Code in das Grid-Element.
<!-- Z-order demonstration. --> <Canvas Grid.Row="1" Grid.Column="1"> <WindowsFormsHost Canvas.Top="20" Canvas.Left="20" Background="Yellow"> <wf:Button Text="Windows Forms control" FlatStyle="Flat"/> </WindowsFormsHost> <Label Content="A WPF label" FontSize="24"/> </Canvas>
Drücken Sie F5, um die Anwendung zu erstellen und auszuführen. Das WindowsFormsHost-Element wird über das Bezeichnungselement gezeichnet.
Andocken
Das WindowsFormsHost-Element unterstützt das WPF-Andocken. Legen Sie die Eigenschaft „Dock angehängt“ fest, um das gehostete Steuerelement in einem DockPanel-Element anzudocken.
Führen Sie die folgenden Schritte aus, um ein gehostetes Steuerelement anzudocken:
Kopieren Sie den folgenden XAML-Code in das Grid-Element.
<!-- Docking a WindowsFormsHost element. --> <DockPanel LastChildFill="false" Grid.Row="2" Grid.Column="1"> <WindowsFormsHost DockPanel.Dock="Right" Canvas.Top="20" Canvas.Left="20" Background="Yellow"> <wf:Button Text="Windows Forms control" FlatStyle="Flat"/> </WindowsFormsHost> </DockPanel>
Drücken Sie F5, um die Anwendung zu erstellen und auszuführen. Das WindowsFormsHost-Element wird an der rechten Seite des DockPanel-Elements angedockt.
Einstellen der Sichtbarkeit
Sie können Ihr Windows Forms-Steuerelement unsichtbar machen oder ausblenden, indem Sie die Visibility-Eigenschaft des WindowsFormsHost-Elements festlegen. Wenn ein Steuerelement unsichtbar ist, wird es nicht angezeigt, es belegt jedoch Platz im Layoutbereich. Wenn ein Steuerelement reduziert ist, wird es nicht angezeigt, und es belegt auch keinen Platz im Layoutbereich.
Führen Sie die folgenden Schritte aus, um die Sichtbarkeit eines gehosteten Steuerelements festzulegen:
Kopieren Sie den folgenden XAML-Code in das Grid-Element.
<!-- Setting Visibility to hidden and collapsed. --> <StackPanel Grid.Row="3" Grid.Column="1"> <Button Name="button2" Click="button2_Click" Content="Click to make invisible" Background="OrangeRed"/> <WindowsFormsHost Name="host1" Background="Yellow"> <wf:Button Text="Windows Forms control" FlatStyle="Flat"/> </WindowsFormsHost> <Button Name="button3" Click="button3_Click" Content="Click to collapse" Background="OrangeRed"/> </StackPanel>
Kopieren Sie in MainWindow.xaml.vb oder MainWindow.xaml.cs den folgenden Code in die Klassendefinition:
private void button2_Click(object sender, EventArgs e) { this.host1.Visibility = Visibility.Hidden; } private void button3_Click(object sender, EventArgs e) { this.host1.Visibility = Visibility.Collapsed; }
Private Sub button2_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Me.host1.Visibility = Windows.Visibility.Hidden End Sub Private Sub button3_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Me.host1.Visibility = Windows.Visibility.Collapsed End Sub
Drücken Sie F5, um die Anwendung zu erstellen und auszuführen.
Klicken Sie auf die Schaltfläche Zum Unsichtbarmachen klicken, um das WindowsFormsHost-Element unsichtbar zu machen.
Klicken Sie auf die Schaltfläche Zum Ausblenden klicken, um das WindowsFormsHost-Element vollständig aus dem Layout auszublenden. Wenn das Windows Forms-Steuerelement ausgeblendet ist, werden die umgebenden Elemente neu angeordnet, um seinen Bereich einzunehmen.
Hosten eines Steuerelements, das nicht gestreckt wird
Einige Windows Forms-Steuerelemente haben eine feste Größe und können nicht gestreckt werden, um den verfügbaren Platz im Layout auszufüllen. Das MonthCalendar-Steuerelement zeigt zum Beispiel einen Monat in einem festen Bereich an.
Führen Sie die folgenden Schritte aus, um ein Steuerelement zu hosten, das nicht gestreckt wird:
Kopieren Sie den folgenden XAML-Code in das Grid-Element.
<!-- Hosting a control that does not stretch. --> <!-- The MonthCalendar has a discrete size. --> <StackPanel Grid.Row="4" Grid.Column="1"> <Label Content="A WPF element" Background="OrangeRed"/> <WindowsFormsHost Background="Yellow"> <wf:MonthCalendar/> </WindowsFormsHost> <Label Content="Another WPF element" Background="OrangeRed"/> </StackPanel>
Drücken Sie F5, um die Anwendung zu erstellen und auszuführen. Das WindowsFormsHost-Element wird in der Rasterzeile zentriert, aber nicht gestreckt, um den verfügbaren Platz auszufüllen. Wenn das Fenster groß genug ist, sehen Sie möglicherweise zwei oder mehr Monate durch das gehostete MonthCalendar-Steuerelement angezeigt, jedoch werden diese in der Zeile zentriert. Die WPF-Layout-Engine zentriert Elemente, deren Größe nicht geändert werden kann, um den verfügbaren Platz auszufüllen.
Skalierung
Im Gegensatz zu WPF-Elementen sind die meisten Windows Forms-Steuerelemente nicht kontinuierlich skalierbar. Um eine benutzerdefinierte Skalierung bereitzustellen, überschreiben Sie die WindowsFormsHost.ScaleChild-Methode.
Führen Sie die folgenden Schritte aus, um ein gehostetes Steuerelement mithilfe des Standardverhaltens zu skalieren:
Kopieren Sie den folgenden XAML-Code in das Grid-Element.
<!-- Scaling transformation. --> <StackPanel Grid.Row="0" Grid.Column="2"> <StackPanel.RenderTransform> <ScaleTransform CenterX="0" CenterY="0" ScaleX="0.5" ScaleY="0.5" /> </StackPanel.RenderTransform> <Label Content="A WPF UIElement" Background="OrangeRed"/> <WindowsFormsHost Background="Yellow"> <wf:Button Text="Windows Forms control" FlatStyle="Flat"/> </WindowsFormsHost> <Label Content="Another WPF UIElement" Background="OrangeRed"/> </StackPanel>
Drücken Sie F5, um die Anwendung zu erstellen und auszuführen. Das gehostete Steuerelement und die umgebenden Elemente werden um den Faktor 0,5 skaliert. Allerdings wird die Schriftart des gehosteten Steuerelements nicht skaliert.
Drehen
Im Gegensatz zu WPF-Elementen unterstützen Windows Forms-Steuerelemente keine Drehung. Das WindowsFormsHost-Element dreht sich nicht mit anderen WPF-Elementen, wenn eine Rotationstransformation angewendet wird. Jeder andere Drehwert als 180 Grad löst das Ereignis LayoutError aus.
Gehen Sie folgendermaßen vor, um die Auswirkungen der Drehung in einer Hybridanwendung zu sehen:
Kopieren Sie den folgenden XAML-Code in das Grid-Element.
<!-- Rotation transformation. --> <StackPanel Grid.Row="1" Grid.Column="2"> <StackPanel.RenderTransform> <RotateTransform CenterX="200" CenterY="50" Angle="180" /> </StackPanel.RenderTransform> <Label Content="A WPF element" Background="OrangeRed"/> <WindowsFormsHost Background="Yellow"> <wf:Button Text="Windows Forms control" FlatStyle="Flat"/> </WindowsFormsHost> <Label Content="Another WPF element" Background="OrangeRed"/> </StackPanel>
Drücken Sie F5, um die Anwendung zu erstellen und auszuführen. Das gehostete Steuerelement wird nicht gedreht, die umgebenden Elemente werden jedoch um einen Winkel von 180 Grad gedreht. Sie müssen möglicherweise die Fenstergröße anpassen, um die Elemente zu sehen.
Einstellen von Abständen und Rändern
Abstand und Ränder im WPF-Layout ähneln den Abständen und Rändern in Windows Forms. Legen Sie einfach die Eigenschaften Padding und Margin für das WindowsFormsHost-Element fest.
Führen Sie die folgenden Schritte aus, um Abstand und Ränder für ein gehostetes Steuerelement festzulegen:
Kopieren Sie den folgenden XAML-Code in das Grid-Element.
<!-- Padding. --> <Canvas Grid.Row="2" Grid.Column="2"> <WindowsFormsHost Padding="0, 20, 0, 0" Background="Yellow"> <wf:Button Text="Windows Forms control with padding" FlatStyle="Flat"/> </WindowsFormsHost> </Canvas>
<!-- Margin. --> <Canvas Grid.Row="3" Grid.Column="2"> <WindowsFormsHost Margin="20, 20, 0, 0" Background="Yellow"> <wf:Button Text="Windows Forms control with margin" FlatStyle="Flat"/> </WindowsFormsHost> </Canvas>
Drücken Sie F5, um die Anwendung zu erstellen und auszuführen. Die Einstellungen für Ränder und Abstände werden wie in Windows Forms auf die gehosteten Windows Forms-Steuerelemente angewendet.
Verwenden von dynamischen Layoutcontainern
Windows Forms bietet zwei dynamische Layoutcontainer, FlowLayoutPanel und TableLayoutPanel. Sie können diese Container auch in WPF-Layouts verwenden.
Führen Sie die folgenden Schritte aus, um einen dynamischen Layoutcontainer zu verwenden:
Kopieren Sie den folgenden XAML-Code in das Grid-Element.
<!-- Flow layout. --> <DockPanel Grid.Row="4" Grid.Column="2"> <WindowsFormsHost Name="flowLayoutHost" Background="Yellow"> <wf:FlowLayoutPanel/> </WindowsFormsHost> </DockPanel>
Kopieren Sie in MainWindow.xaml.vb oder MainWindow.xaml.cs den folgenden Code in die Klassendefinition:
private void InitializeFlowLayoutPanel() { System.Windows.Forms.FlowLayoutPanel flp = this.flowLayoutHost.Child as System.Windows.Forms.FlowLayoutPanel; flp.WrapContents = true; const int numButtons = 6; for (int i = 0; i < numButtons; i++) { System.Windows.Forms.Button b = new System.Windows.Forms.Button(); b.Text = "Button"; b.BackColor = System.Drawing.Color.AliceBlue; b.FlatStyle = System.Windows.Forms.FlatStyle.Flat; flp.Controls.Add(b); } }
Private Sub InitializeFlowLayoutPanel() Dim flp As System.Windows.Forms.FlowLayoutPanel = Me.flowLayoutHost.Child flp.WrapContents = True Const numButtons As Integer = 6 Dim i As Integer For i = 0 To numButtons Dim b As New System.Windows.Forms.Button() b.Text = "Button" b.BackColor = System.Drawing.Color.AliceBlue b.FlatStyle = System.Windows.Forms.FlatStyle.Flat flp.Controls.Add(b) Next i End Sub
Fügen Sie einen Aufruf der
InitializeFlowLayoutPanel
-Methode im Konstruktor hinzu:public MainWindow() { InitializeComponent(); this.InitializeFlowLayoutPanel(); }
Public Sub New() InitializeComponent() Me.InitializeFlowLayoutPanel() End Sub
Drücken Sie F5, um die Anwendung zu erstellen und auszuführen. Das WindowsFormsHost-Element füllt das DockPanel, und das FlowLayoutPanel ordnet seine untergeordneten Steuerelemente in der standardmäßigen FlowDirection an.
Weitere Informationen
- ElementHost
- WindowsFormsHost
- Entwerfen von XAML-Code in Visual Studio
- Überlegungen zum Layout für das WindowsFormsHost-Element
- Exemplarische Vorgehensweise: Anordnen von Windows Forms-Steuerelementen in WPF
- Exemplarische Vorgehensweise: Hosten eines zusammengesetzten Windows Forms-Steuerelements in WPF
- Exemplarische Vorgehensweise: Hosten eines zusammengesetzten WPF-Steuerelements in Windows Forms
.NET Desktop feedback