Exemplarische Vorgehensweise: Hosten eines zusammengesetzten Windows Forms-Steuerelements in WPF

Windows Presentation Foundation (WPF) bietet eine umfangreiche Umgebung zum Erstellen von Anwendungen. Wenn Sie allerdings bereits erheblichen Aufwand in Windows Forms-Code investiert haben, kann es effektiver sein, zumindest einen Teil dieses Codes in Ihrer WPF-Anwendung wiederzuverwenden, anstatt ihn vollständig neu zu schreiben. Das häufigste Szenario ist, wenn Sie bereits Windows Forms-Steuerelemente haben. In einigen Fällen können Sie vielleicht gar nicht mehr auf den Quellcode für diese Steuerelemente zugreifen. WPF bietet ein einfaches Verfahren zum Hosten solcher Steuerelemente in einer WPF-Anwendung. Sie können WPF beispielsweise für den größten Teil Ihrer Programmierung verwenden, während Ihre spezialisierten DataGridView-Steuerelemente gehostet werden.

Diese exemplarische Vorgehensweise führt Sie durch eine Anwendung, die ein zusammengesetztes Windows Forms-Steuerelement zur Dateneingabe in einer WPF-Anwendung hostet. Das zusammengesetzte Steuerelement ist in eine DLL verpackt. Dieses allgemeine Verfahren kann für komplexere Anwendungen und Steuerelemente erweitert werden. Diese exemplarische Vorgehensweise wurde so gestaltet, dass sie in Darstellung und Funktionalität nahezu identisch mit Exemplarische Vorgehensweise: Hosten eines zusammengesetzten WPF-Steuerelements in Windows Forms ist. Der Hauptunterschied besteht darin, dass das Hosting-Szenario umgekehrt ist.

Diese exemplarische Vorgehensweise ist in zwei Abschnitte unterteilt. Im ersten Abschnitt wird die Implementierung des zusammengesetzten Windows Forms-Steuerelements kurz beschrieben. Im zweiten Abschnitt wird detailliert erläutert, wie Sie das zusammengesetzte Steuerelement in einer WPF-Anwendung hosten, Ereignisse vom Steuerelement empfangen und auf einige Eigenschaften des Steuerelements zugreifen können.

In dieser exemplarischen Vorgehensweise werden u. a. folgende Aufgaben veranschaulicht:

  • Implementieren des zusammengesetzten Windows Forms-Steuerelements.

  • Implementieren der WPF-Hostanwendung.

Eine vollständige Codeauflistung der Aufgaben in dieser exemplarischen Vorgehensweise finden Sie unter Beispiel zum Hosten eines zusammengesetzten Windows Forms-Steuerelements in WPF.

Voraussetzungen

Für diese exemplarische Vorgehensweise benötigen Sie Visual Studio.

Implementieren des zusammengesetzten Windows Forms-Steuerelements

Das in diesem Beispiel verwendete zusammengesetzte Windows Forms-Steuerelement ist ein einfaches Dateneingabeformular. Dieses Formular erfasst den Namen und die Adresse des Benutzers und gibt diese Information unter Verwendung eines benutzerdefinierten Ereignisses an den Host zurück. Die folgende Abbildung zeigt das gerenderte Steuerelement.

Die folgende Abbildung zeigt ein zusammengesetztes Windows Forms-Steuerelement:

Screenshot that shows a simple Windows Forms control.

Erstellen des Projekts

Um das Projekt zu starten:

  1. Starten Sie Visual Studio, und öffnen Sie das Dialogfeld Neues Projekt.

  2. Wählen Sie in der Kategorie „Windows” die Vorlage Windows Forms-Steuerelementbibliothek aus.

  3. Geben Sie dem neuen Projekt den Namen MyControls.

  4. Geben Sie als Speicherort einen entsprechend benannten Ordner der obersten Ebene an, z. B. WpfHostingWindowsFormsControl. Sie werden die Host-Anwendung später in diesem Ordner ablegen.

  5. Klicken Sie auf OK, um das Projekt zu erstellen. Das Standardprojekt enthält ein einzelnes Steuerelement namens UserControl1.

  6. Benennen Sie im Projektmappen-Explorer UserControl1 in MyControl1 um.

Das Projekt sollte Verweise auf die folgenden System-DLLs aufweisen. Sollten eine oder mehrere dieser DLLs nicht standardmäßig enthalten sein, fügen Sie diese manuell zum Projekt hinzu.

  • System

  • System.Data

  • System.Drawing

  • System.Windows.Forms

  • System.Xml

Hinzufügen von Steuerelementen zum Formular

So fügen Sie dem Formular Steuerelemente hinzu:

  • Öffnen Sie MyControl1 im Designer.

Fügen Sie auf dem Formular fünf Label-Steuerelemente und deren entsprechende TextBox-Steuerelemente hinzu, und zwar mit der gleichen Größe und Anordnung wie in der vorstehenden Abbildung. Im Beispiel sind die TextBox-Steuerelemente benannt:

  • txtName

  • txtAddress

  • txtCity

  • txtState

  • txtZip

Fügen Sie zwei Button-Steuerelemente mit der Bezeichnung OK und Abbrechen hinzu. Im Beispiel lauten die Namen der Schaltflächen btnOK und btnCancel.

Implementieren des unterstützenden Codes

Öffnen Sie das Formular in der Codeansicht. Das Steuerelement gibt die gesammelten Daten durch Auslösen des benutzerdefinierten OnButtonClick-Ereignisses an seinen Host weiter. Die Daten sind im Ereignisargumentobjekt enthalten. Der folgende Code zeigt die Deklaration von Ereignis und Delegat.

Fügen Sie der MyControl1 -Klasse den folgenden Code hinzu.

public delegate void MyControlEventHandler(object sender, MyControlEventArgs args);
public event MyControlEventHandler OnButtonClick;
Public Delegate Sub MyControlEventHandler(ByVal sender As Object, ByVal args As MyControlEventArgs)
Public Event OnButtonClick As MyControlEventHandler

Die Klasse MyControlEventArgs enthält die Informationen, die an den Host zurückgegeben werden sollen.

Fügen Sie dem Formular die folgende Klasse hinzu.

public class MyControlEventArgs : EventArgs
{
    private string _Name;
    private string _StreetAddress;
    private string _City;
    private string _State;
    private string _Zip;
    private bool _IsOK;

    public MyControlEventArgs(bool result,
                                   string name,
                                   string address,
                                   string city,
                                   string state,
                                   string zip)
    {
        _IsOK = result;
        _Name = name;
        _StreetAddress = address;
        _City = city;
        _State = state;
        _Zip = zip;
    }

    public string MyName
    {
        get { return _Name; }
        set { _Name = value; }
    }
    public string MyStreetAddress
    {
        get { return _StreetAddress; }
        set { _StreetAddress = value; }
    }
    public string MyCity
    {
        get { return _City; }
        set { _City = value; }
    }
    public string MyState
    {
        get { return _State; }
        set { _State = value; }
    }
    public string MyZip
    {
        get { return _Zip; }
        set { _Zip = value; }
    }
    public bool IsOK
    {
        get { return _IsOK; }
        set { _IsOK = value; }
    }
}
Public Class MyControlEventArgs
    Inherits EventArgs
    Private _Name As String
    Private _StreetAddress As String
    Private _City As String
    Private _State As String
    Private _Zip As String
    Private _IsOK As Boolean
    
    
    Public Sub New(ByVal result As Boolean, ByVal name As String, ByVal address As String, ByVal city As String, ByVal state As String, ByVal zip As String) 
        _IsOK = result
        _Name = name
        _StreetAddress = address
        _City = city
        _State = state
        _Zip = zip
    
    End Sub
    
    
    Public Property MyName() As String 
        Get
            Return _Name
        End Get
        Set
            _Name = value
        End Set
    End Property
    
    Public Property MyStreetAddress() As String 
        Get
            Return _StreetAddress
        End Get
        Set
            _StreetAddress = value
        End Set
    End Property
    
    Public Property MyCity() As String 
        Get
            Return _City
        End Get
        Set
            _City = value
        End Set
    End Property
    
    Public Property MyState() As String 
        Get
            Return _State
        End Get
        Set
            _State = value
        End Set
    End Property
    
    Public Property MyZip() As String 
        Get
            Return _Zip
        End Get
        Set
            _Zip = value
        End Set
    End Property
    
    Public Property IsOK() As Boolean 
        Get
            Return _IsOK
        End Get
        Set
            _IsOK = value
        End Set
    End Property
End Class

Wenn der Benutzer auf die Schaltfläche OK oder Abbrechen klickt, erstellen die Ereignishandler Click ein MyControlEventArgs-Objekt, das die Daten enthält und das OnButtonClick-Ereignis auslöst. Der einzige Unterschied zwischen den beiden Handlern ist die Eigenschaft IsOK des Ereignisarguments. Diese Eigenschaft ermöglicht es dem Host, zu bestimmen, auf welche Schaltfläche geklickt wurde. Ihr Wert wird bei der Schaltfläche OK auf true und bei der Schaltfläche Abbrechen auf false festgelegt. Der folgende Code zeigt die Handler der Schaltflächen.

Fügen Sie der MyControl1 -Klasse den folgenden Code hinzu.

private void btnOK_Click(object sender, System.EventArgs e)
{

    MyControlEventArgs retvals = new MyControlEventArgs(true,
                                                         txtName.Text,
                                                         txtAddress.Text,
                                                         txtCity.Text,
                                                         txtState.Text,
                                                         txtZip.Text);
    OnButtonClick(this, retvals);
}

private void btnCancel_Click(object sender, System.EventArgs e)
{
    MyControlEventArgs retvals = new MyControlEventArgs(false,
                                                         txtName.Text,
                                                         txtAddress.Text,
                                                         txtCity.Text,
                                                         txtState.Text,
                                                         txtZip.Text);
    OnButtonClick(this, retvals);
}
Private Sub btnOK_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOK.Click

    Dim retvals As New MyControlEventArgs(True, txtName.Text, txtAddress.Text, txtCity.Text, txtState.Text, txtZip.Text)
    RaiseEvent OnButtonClick(Me, retvals)

End Sub

Private Sub btnCancel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnCancel.Click
    Dim retvals As New MyControlEventArgs(False, txtName.Text, txtAddress.Text, txtCity.Text, txtState.Text, txtZip.Text)
    RaiseEvent OnButtonClick(Me, retvals)

End Sub

Vergeben eines starken Namens für die Assembly und Erstellen der Assembly

Damit auf diese Assembly von einer WPF-Anwendung verwiesen werden kann, muss sie einen starken Namen haben. Zum Erstellen eines starken Namens erstellen Sie mit „Sn.exe“ eine Schlüsseldatei und fügen Sie Ihrem Projekt hinzu.

  1. Öffnen Sie eine Visual Studio-Eingabeaufforderung. Klicken Sie dazu auf Start, und wählen Sie Alle Programme/Microsoft Visual Studio 2010/Visual Studio-Tools/Visual Studio-Eingabeaufforderung aus. Dadurch wird ein Konsolenfenster mit benutzerdefinierten Umgebungsvariablen gestartet.

  2. Geben Sie an der Eingabeaufforderung den Befehl cd ein, um zu Ihrem Projektordner zu wechseln.

  3. Generieren Sie durch Ausführen des folgenden Befehls eine Schlüsseldatei mit dem Namen MyControls.snk.

    Sn.exe -k MyControls.snk
    
  4. Um diese Schlüsseldatei in Ihr Projekt einzubeziehen, klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Projektnamen. Klicken Sie dann auf Eigenschaften. Klicken Sie im Projekt-Designer auf die Registerkarte Signierung, aktivieren Sie das Kontrollkästchen Assembly signieren, und navigieren Sie zu Ihrer Schlüsseldatei.

  5. Erstellen Sie die Projektmappe. Der Build erzeugt eine DLL mit dem Namen MyControls.dll.

Implementieren der WPF-Hostanwendung

Die WPF-Hostanwendung verwendet das Steuerelement WindowsFormsHost zum Hosten von MyControl1. Die Anwendung verarbeitet das OnButtonClick-Ereignis, um die Daten aus dem Steuerelement zu empfangen. Außerdem enthält sie eine Auflistung von Optionsschaltflächen, mit denen Sie einige Eigenschaften des Steuerelements aus der WPF-Anwendung heraus ändern können. Die folgende Abbildung zeigt die fertige Anwendung.

Die folgende Abbildung zeigt die vollständige WPF-Anwendung, einschließlich des darin eingebetteten Steuerelements:

Screenshot that shows a control embedded in a WPF page.

Erstellen des Projekts

Um das Projekt zu starten:

  1. Öffnen Sie Visual Studio, und wählen Sie Neues Projekt aus.

  2. Wählen Sie in der Kategorie „Windows” die Vorlage WPF-Anwendung aus.

  3. Geben Sie dem neuen Projekt den Namen WpfHost.

  4. Geben Sie für den Speicherort denselben Stammordner an, der das Projekt „MyControls” enthält.

  5. Klicken Sie auf OK, um das Projekt zu erstellen.

Sie müssen auch Verweise auf die DLL, die MyControl1 enthält, und auf andere Assemblys hinzufügen.

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Projektnamen, und wählen Sie Verweis hinzufügen aus.

  2. Klicken Sie auf die Registerkarte Durchsuchen, und navigieren Sie zu dem Ordner mit „MyControls.dll“. In dieser exemplarischen Vorgehensweise ist dies der Ordner "MyControls\bin\Debug".

  3. Wählen Sie „MyControls.dll“ aus, und klicken Sie auf OK.

  4. Fügen Sie einen Verweis auf die Assembly „WindowsFormsIntegration” hinzu, deren Name „WindowsFormsIntegration.dll” lautet.

Implementieren des grundlegenden Layouts

Die Benutzeroberfläche der Hostanwendung ist in „MainWindow.xaml“ implementiert. Diese Datei enthält das XAML-Markup (Extensible Application Markup Language), von dem das Layout definiert und das Windows Forms-Steuerelement gehostet wird. Die Anwendung ist in drei Bereiche unterteilt:

  • Den Bereich Steuerelementeigenschaften, der eine Auflistung von Optionsschaltflächen enthält, mit denen Sie verschiedene Eigenschaften des gehosteten Steuerelements ändern können.

  • Den Bereich Daten aus Steuerelement, der mehrere TextBlock-Elemente enthält, die die vom gehosteten Steuerelement zurückgegebenen Daten anzeigen.

  • Das gehostete Steuerelement selbst.

Das grundlegende Layout ist im nachfolgenden XAML-Code beschrieben. Das zum Hosten von MyControl1 benötigte Markup wurde in diesem Beispiel weggelassen, wird aber später erläutert.

Ersetzen Sie den XAML-Code in der Datei MainWindow.xaml durch den folgenden Code. Wenn Sie Visual Basic verwenden, ändern Sie die Klasse in x:Class="MainWindow".

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="WpfHost.MainWindow"
      xmlns:mcl="clr-namespace:MyControls;assembly=MyControls"
      Loaded="Init">
  <DockPanel>
    <DockPanel.Resources>
      <Style x:Key="inlineText" TargetType="{x:Type Inline}">
        <Setter Property="FontWeight" Value="Normal"/>
      </Style>
      <Style x:Key="titleText" TargetType="{x:Type TextBlock}">
        <Setter Property="DockPanel.Dock" Value="Top"/>
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="Margin" Value="10,5,10,0"/>
      </Style>
    </DockPanel.Resources>

    <StackPanel Orientation="Vertical"
                DockPanel.Dock="Left"
                Background="Bisque"
                Width="250">

      <TextBlock  Margin="10,10,10,10"
                  FontWeight="Bold"
                  FontSize="12">Control Properties</TextBlock>
      <TextBlock Style="{StaticResource titleText}">Background Color</TextBlock>
      <StackPanel Margin="10,10,10,10">
        <RadioButton Name="rdbtnOriginalBackColor"
                    IsChecked="True"
                    Click="BackColorChanged">Original</RadioButton>
        <RadioButton Name="rdbtnBackGreen"
                    Click="BackColorChanged">LightGreen</RadioButton>
        <RadioButton Name="rdbtnBackSalmon"
                    Click="BackColorChanged">LightSalmon</RadioButton>
      </StackPanel>

      <TextBlock Style="{StaticResource titleText}">Foreground Color</TextBlock>
      <StackPanel Margin="10,10,10,10">
        <RadioButton Name="rdbtnOriginalForeColor"
                    IsChecked="True"
                    Click="ForeColorChanged">Original</RadioButton>
        <RadioButton Name="rdbtnForeRed"
                    Click="ForeColorChanged">Red</RadioButton>
        <RadioButton Name="rdbtnForeYellow"
                    Click="ForeColorChanged">Yellow</RadioButton>
      </StackPanel>

      <TextBlock Style="{StaticResource titleText}">Font Family</TextBlock>
      <StackPanel Margin="10,10,10,10">
        <RadioButton Name="rdbtnOriginalFamily"
                     IsChecked="True"
                    Click="FontChanged">Original</RadioButton>
        <RadioButton Name="rdbtnTimes"
                    Click="FontChanged">Times New Roman</RadioButton>
        <RadioButton Name="rdbtnWingdings"
                    Click="FontChanged">Wingdings</RadioButton>
      </StackPanel>

      <TextBlock Style="{StaticResource titleText}">Font Size</TextBlock>
      <StackPanel Margin="10,10,10,10">
        <RadioButton Name="rdbtnOriginalSize"
                    IsChecked="True"
                    Click="FontSizeChanged">Original</RadioButton>
        <RadioButton Name="rdbtnTen"
                    Click="FontSizeChanged">10</RadioButton>
        <RadioButton Name="rdbtnTwelve"
                    Click="FontSizeChanged">12</RadioButton>
      </StackPanel>

      <TextBlock Style="{StaticResource titleText}">Font Style</TextBlock>
      <StackPanel Margin="10,10,10,10">
        <RadioButton Name="rdbtnNormalStyle"
                     IsChecked="True"
                     Click="StyleChanged">Original</RadioButton>
        <RadioButton Name="rdbtnItalic"
                     Click="StyleChanged">Italic</RadioButton>
      </StackPanel>

      <TextBlock Style="{StaticResource titleText}">Font Weight</TextBlock>
      <StackPanel Margin="10,10,10,10">
        <RadioButton Name="rdbtnOriginalWeight"
                     IsChecked="True"
                   Click="WeightChanged">
          Original
        </RadioButton>
        <RadioButton Name="rdbtnBold"
                   Click="WeightChanged">Bold</RadioButton>
      </StackPanel>
    </StackPanel>

    <WindowsFormsHost Name="wfh"
                     DockPanel.Dock="Top"
                     Height="300">
      <mcl:MyControl1 Name="mc"/>
    </WindowsFormsHost>
    
    <StackPanel Orientation="Vertical"
                Height="Auto"
                Background="LightBlue">
      <TextBlock Margin="10,10,10,10"
            FontWeight="Bold"
            FontSize="12">Data From Control</TextBlock>
      <TextBlock Style="{StaticResource titleText}">
        Name: <Span Name="txtName" Style="{StaticResource inlineText}"/>
      </TextBlock>
      <TextBlock Style="{StaticResource titleText}">
        Street Address: <Span Name="txtAddress" Style="{StaticResource inlineText}"/>
      </TextBlock>
      <TextBlock Style="{StaticResource titleText}">
        City: <Span Name="txtCity" Style="{StaticResource inlineText}"/>
      </TextBlock>
      <TextBlock Style="{StaticResource titleText}">
        State: <Span Name="txtState" Style="{StaticResource inlineText}"/>
      </TextBlock>
      <TextBlock Style="{StaticResource titleText}">
        Zip: <Span Name="txtZip" Style="{StaticResource inlineText}"/>
      </TextBlock>
    </StackPanel>
  </DockPanel>
</Window>

Das erste StackPanel-Element enthält mehrere Gruppen von RadioButton-Steuerelementen, mit denen Sie verschiedene Standardeigenschaften des gehosteten Steuerelements ändern können. Darauf folgt ein WindowsFormsHost-Element, das MyControl1 hostet. Das letzte StackPanel-Element enthält mehrere TextBlock-Elemente, die die vom gehosteten Steuerelement zurückgegebenen Daten anzeigen. Die Reihenfolge der Elemente sowie die Einstellungen der Attribute Dock und Height betten das gehostete Steuerelement ohne Lücken oder Verzerrung in das Fenster ein.

Hosten des Steuerelements

Die folgende bearbeitete Version des vorigen XAML-Codes konzentriert sich auf die Elemente, die zum Hosten von MyControl1 benötigt werden.

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="WpfHost.MainWindow"
      xmlns:mcl="clr-namespace:MyControls;assembly=MyControls"
      Loaded="Init">
<WindowsFormsHost Name="wfh"
                 DockPanel.Dock="Top"
                 Height="300">
  <mcl:MyControl1 Name="mc"/>
</WindowsFormsHost>

Das Namespace-Zuordnungsattribut xmlns erstellt einen Verweis auf den Namespace MyControls, der das gehostete Steuerelement enthält. Diese Zuordnung ermöglicht es Ihnen, MyControl1 in XAML als <mcl:MyControl1> darzustellen.

Das Hosting wird im XAML-Code von zwei Elementen behandelt:

  • WindowsFormsHost stellt das Element WindowsFormsHost dar, mit dem Sie ein Windows Forms-Steuerelement in einer WPF-Anwendung hosten können.

  • mcl:MyControl1, das MyControl1 darstellt, wird der untergeordneten Auflistung des Elements WindowsFormsHost hinzugefügt. Dies führt dazu, dass dieses Windows Forms-Steuerelement als Teil des WPF-Fensters gerendert wird und Sie mit dem Steuerelement aus der Anwendung heraus kommunizieren können.

Implementieren der CodeBehind-Datei

Die CodeBehind-Datei „MainWindow.Xaml.vb“ bzw. „MainWindow.Xaml.cs“ enthält den prozeduralen Code, der die im vorhergehenden Abschnitt erläuterte Funktionalität der Benutzeroberfläche implementiert. Die Hauptaufgaben sind:

  • Einen Ereignishandler an das OnButtonClick von MyControl1-Ereignis anzufügen.

  • Verschiedene Eigenschaften von MyControl1 basierend auf den Werten aller Optionsfelder zu ändern.

  • Die Daten, die durch das Steuerelement gesammelt wurden, anzuzeigen.

Initialisierung der Anwendung

Der Initialisierungscode ist in einem Ereignishandler für das Loaded-Ereignis des Fensters enthalten und fügt einen Ereignishandler an das OnButtonClick-Ereignis des Steuerelements an.

Fügen Sie in „MainWindow.xaml.vb“ oder „MainWindow.xaml.cs“ der Klasse MainWindow den folgenden Code hinzu.

private Application app;
private Window myWindow;
FontWeight initFontWeight;
Double initFontSize;
FontStyle initFontStyle;
SolidColorBrush initBackBrush;
SolidColorBrush initForeBrush;
FontFamily initFontFamily;
bool UIIsReady = false;

private void Init(object sender, EventArgs e)
{
    app = System.Windows.Application.Current;
    myWindow = (Window)app.MainWindow;
    myWindow.SizeToContent = SizeToContent.WidthAndHeight;
    wfh.TabIndex = 10;
    initFontSize = wfh.FontSize;
    initFontWeight = wfh.FontWeight;
    initFontFamily = wfh.FontFamily;
    initFontStyle = wfh.FontStyle;
    initBackBrush = (SolidColorBrush)wfh.Background;
    initForeBrush = (SolidColorBrush)wfh.Foreground;
    (wfh.Child as MyControl1).OnButtonClick += new MyControl1.MyControlEventHandler(Pane1_OnButtonClick);
    UIIsReady = true;
}
Private app As Application
Private myWindow As Window
Private initFontWeight As FontWeight
Private initFontSize As [Double]
Private initFontStyle As FontStyle
Private initBackBrush As SolidColorBrush
Private initForeBrush As SolidColorBrush
Private initFontFamily As FontFamily
Private UIIsReady As Boolean = False


Private Sub Init(ByVal sender As Object, ByVal e As RoutedEventArgs)
    app = System.Windows.Application.Current
    myWindow = CType(app.MainWindow, Window)
    myWindow.SizeToContent = SizeToContent.WidthAndHeight
    wfh.TabIndex = 10
    initFontSize = wfh.FontSize
    initFontWeight = wfh.FontWeight
    initFontFamily = wfh.FontFamily
    initFontStyle = wfh.FontStyle
    initBackBrush = CType(wfh.Background, SolidColorBrush)
    initForeBrush = CType(wfh.Foreground, SolidColorBrush)

    Dim mc As MyControl1 = wfh.Child

    AddHandler mc.OnButtonClick, AddressOf Pane1_OnButtonClick
    UIIsReady = True

End Sub

Weil der weiter oben erläuterte XAML-Code das Steuerelement MyControl1 zur Auflistung von untergeordneten Elementen des Elements WindowsFormsHost hinzugefügt hat, können Sie den Wert Child des Elements WindowsFormsHost umwandeln, um den Verweis auf MyControl1 zu erhalten. Diesen Verweis können Sie dann verwenden, um einen Ereignishandler an OnButtonClick anzufügen.

WindowsFormsHost stellt nicht nur einen Verweis auf das Steuerelement selbst bereit, sondern macht auch eine Reihe von Eigenschaften des Steuerelements verfügbar, die Sie aus der Anwendung heraus anpassen können. Der Initialisierungscode weist diese Werte privaten globalen Variablen zu, damit sie später in der Anwendung verfügbar sind.

Damit Sie auf die Typen in der DLL MyControls problemlos zugreifen können, fügen Sie am Dateianfang die folgende Imports- bzw. using-Anweisung hinzu.

Imports MyControls
using MyControls;

Behandeln des OnButtonClick-Ereignisses

MyControl1 löst das OnButtonClick-Ereignis aus, wenn der Benutzer auf eine der Schaltflächen des Steuerelements klickt.

Fügen Sie der MainWindow -Klasse den folgenden Code hinzu.

//Handle button clicks on the Windows Form control
private void Pane1_OnButtonClick(object sender, MyControlEventArgs args)
{
    txtName.Inlines.Clear();
    txtAddress.Inlines.Clear();
    txtCity.Inlines.Clear();
    txtState.Inlines.Clear();
    txtZip.Inlines.Clear();

    if (args.IsOK)
    {
        txtName.Inlines.Add( " " + args.MyName );
        txtAddress.Inlines.Add( " " + args.MyStreetAddress );
        txtCity.Inlines.Add( " " + args.MyCity );
        txtState.Inlines.Add( " " + args.MyState );
        txtZip.Inlines.Add( " " + args.MyZip );
    }
}
'Handle button clicks on the Windows Form control
Private Sub Pane1_OnButtonClick(ByVal sender As Object, ByVal args As MyControlEventArgs)
    txtName.Inlines.Clear()
    txtAddress.Inlines.Clear()
    txtCity.Inlines.Clear()
    txtState.Inlines.Clear()
    txtZip.Inlines.Clear()

    If args.IsOK Then
        txtName.Inlines.Add(" " + args.MyName)
        txtAddress.Inlines.Add(" " + args.MyStreetAddress)
        txtCity.Inlines.Add(" " + args.MyCity)
        txtState.Inlines.Add(" " + args.MyState)
        txtZip.Inlines.Add(" " + args.MyZip)
    End If

End Sub

Die Daten in den Textfeldern sind in das Objekt MyControlEventArgs verpackt. Wenn der Benutzer auf die Schaltfläche OK klickt, extrahiert der Ereignishandler die Daten und zeigt sie im Bereich unter MyControl1 an.

Ändern der Eigenschaften des Steuerelements

Das Element WindowsFormsHost macht mehrere Standardeigenschaften des gehosteten Steuerelements verfügbar. Daher können Sie die Darstellung des Steuerelements besser dem Format Ihrer Anwendung entsprechend anpassen. Die Gruppe von Optionsschaltflächen im linken Bereich erlauben es dem Benutzer, mehrere Farb- und Schriftart-Eigenschaften zu ändern. Bei jeder Schaltflächengruppe gibt es einen Handler für das Click-Ereignis, der die vom Benutzer getroffene Auswahl an Optionsschaltflächen ermittelt und die entsprechende Eigenschaft im Steuerelement ändert.

Fügen Sie der MainWindow -Klasse den folgenden Code hinzu.

private void BackColorChanged(object sender, RoutedEventArgs e)
{
    if (sender == rdbtnBackGreen)
        wfh.Background = new SolidColorBrush(Colors.LightGreen);
    else if (sender == rdbtnBackSalmon)
        wfh.Background = new SolidColorBrush(Colors.LightSalmon);
    else if (UIIsReady == true)
        wfh.Background = initBackBrush;
}

private void ForeColorChanged(object sender, RoutedEventArgs e)
{
    if (sender == rdbtnForeRed)
        wfh.Foreground = new SolidColorBrush(Colors.Red);
    else if (sender == rdbtnForeYellow)
        wfh.Foreground = new SolidColorBrush(Colors.Yellow);
    else if (UIIsReady == true)
        wfh.Foreground = initForeBrush;
}

private void FontChanged(object sender, RoutedEventArgs e)
{
    if (sender == rdbtnTimes)
        wfh.FontFamily = new FontFamily("Times New Roman");
    else if (sender == rdbtnWingdings)
        wfh.FontFamily = new FontFamily("Wingdings");
    else if (UIIsReady == true)
        wfh.FontFamily = initFontFamily;
}
private void FontSizeChanged(object sender, RoutedEventArgs e)
{
    if (sender == rdbtnTen)
        wfh.FontSize = 10;
    else if (sender == rdbtnTwelve)
        wfh.FontSize = 12;
    else if (UIIsReady == true)
        wfh.FontSize = initFontSize;
}
private void StyleChanged(object sender, RoutedEventArgs e)
{
    if (sender == rdbtnItalic)
        wfh.FontStyle = FontStyles.Italic;
    else if (UIIsReady == true)
        wfh.FontStyle = initFontStyle;
}
private void WeightChanged(object sender, RoutedEventArgs e)
{
    if (sender == rdbtnBold)
        wfh.FontWeight = FontWeights.Bold;
    else if (UIIsReady == true)
        wfh.FontWeight = initFontWeight;
}
Private Sub BackColorChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)

    If sender.Equals(rdbtnBackGreen) Then
        wfh.Background = New SolidColorBrush(Colors.LightGreen)
    ElseIf sender.Equals(rdbtnBackSalmon) Then
        wfh.Background = New SolidColorBrush(Colors.LightSalmon)
    ElseIf UIIsReady = True Then
        wfh.Background = initBackBrush
    End If

End Sub

Private Sub ForeColorChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
    If sender.Equals(rdbtnForeRed) Then
        wfh.Foreground = New SolidColorBrush(Colors.Red)
    ElseIf sender.Equals(rdbtnForeYellow) Then
        wfh.Foreground = New SolidColorBrush(Colors.Yellow)
    ElseIf UIIsReady = True Then
        wfh.Foreground = initForeBrush
    End If

End Sub

Private Sub FontChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
    If sender.Equals(rdbtnTimes) Then
        wfh.FontFamily = New FontFamily("Times New Roman")
    ElseIf sender.Equals(rdbtnWingdings) Then
        wfh.FontFamily = New FontFamily("Wingdings")
    ElseIf UIIsReady = True Then
        wfh.FontFamily = initFontFamily
    End If

End Sub

Private Sub FontSizeChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
    If sender.Equals(rdbtnTen) Then
        wfh.FontSize = 10
    ElseIf sender.Equals(rdbtnTwelve) Then
        wfh.FontSize = 12
    ElseIf UIIsReady = True Then
        wfh.FontSize = initFontSize
    End If

End Sub

Private Sub StyleChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
    If sender.Equals(rdbtnItalic) Then
        wfh.FontStyle = FontStyles.Italic
    ElseIf UIIsReady = True Then
        wfh.FontStyle = initFontStyle
    End If

End Sub

Private Sub WeightChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
    If sender.Equals(rdbtnBold) Then
        wfh.FontWeight = FontWeights.Bold
    ElseIf UIIsReady = True Then
        wfh.FontWeight = initFontWeight
    End If

End Sub

Erstellen Sie die Anwendung, und führen Sie sie aus. Fügen Sie dem zusammengesetzten Windows Forms-Steuerelement etwas Text hinzu, und klicken Sie auf OK. Der Text wird in den Beschriftungen angezeigt. Klicken Sie auf die verschiedenen Optionsfelder, um die Auswirkung auf das Steuerelement zu sehen.

Siehe auch