Condividi tramite


Procedura dettagliata: hosting di controlli Windows Form compositi in Windows Presentation Foundation

Aggiornamento: novembre 2007

Windows Presentation Foundation (WPF) fornisce un ambiente funzionale per la creazione di applicazioni. Tuttavia, quando si dispone di una grande quantità di codice Windows Form, può essere opportuno riutilizzare almeno parte di tale codice nell'applicazione WPF anziché riscriverlo dall'inizio. Lo scenario più comune prevede l'esistenza di controlli Windows Form personalizzati. In alcuni casi non si dispone nemmeno dell'accesso al codice sorgente per questi controlli. WPF fornisce una procedura diretta per l'hosting di tali controlli in un'applicazione WPF. È ad esempio possibile utilizzare WPF per la maggior parte della programmazione pur ospitando i controlli System.Windows.Forms.DataGridView specializzati.

In questa procedura dettagliata viene descritta un'applicazione che ospita un controllo Windows Form composto in una pagina WPF. Questa procedura generale può essere estesa ad applicazioni e controlli più complessi.

La procedura dettagliata è divisa in due sezioni. Nella prima sezione viene brevemente descritta l'implementazione del controllo Windows Form. Nella seconda sezione viene illustrato in dettaglio come ospitare il controllo in un'applicazione WPF, come ricevere eventi dal controllo e come accedere ad alcune delle proprietà del controllo.

Di seguito vengono elencate le attività illustrate nella procedura dettagliata:

  • Implementazione del controllo Windows Form.

  • Implementazione dell'applicazione host con Windows Presentation Foundation.

Per un elenco di codice completo delle attività illustrate in questa procedura dettagliata, vedere Esempio di hosting di controlli Windows Form compositi in Windows Presentation Foundation.

Prerequisiti

Per completare questa procedura dettagliata, è necessario disporre dei seguenti componenti:

  • Visual Studio 2008.

Implementazione del controllo Windows Form

Il controllo Windows Form utilizzato in questo esempio è un semplice form di immissione dati. Questo form accetta il nome e l'indirizzo dell'utente e utilizza un evento personalizzato per restituire tali informazioni all'host. Nell’immagine riportata di seguito viene illustrato il controllo sottoposto a rendering.

Il controllo Windows Form

Controllo Windows Form semplice

Creazione del progetto

Per avviare il progetto:

  1. Avviare Microsoft Visual Studio e aprire la finestra di dialogo Nuovo progetto.

  2. Selezionare Progetti C# con il modello Libreria di controlli Windows Form.

  3. Assegnare al nuovo progetto il nome MyControls e scegliere OK per creare il progetto. Il progetto predefinito contiene un singolo controllo denominato UserControl1.

  4. Modificare il nome di UserControl1 in MyControl1.

Il progetto dovrebbe presentare riferimenti alle DLL di sistema riportate di seguito. Se alcune di queste DLL non sono incluse per impostazione predefinita, aggiungerle al progetto.

  • System

  • System.Data

  • System.Drawing

  • System.Windows.Forms

  • System.XML

Aggiunta di controlli al form

Per aggiungere controlli al form:

  • Aprire la finestra di progettazione per MyControl1.

Posizionare sul form sei controlli System.Windows.Forms.Label e i controlli System.Windows.Forms.TextBox corrispondenti, ridimensionati e disposti come nell'illustrazione precedente. Nell'esempio i controlli TextBox sono denominati:

  • txtName

  • txtAddress

  • txtCity

  • txtState

  • txtZip

Aggiungere due controlli System.Windows.Forms.Button con etichetta OK e Annulla. Nell'esempio i nomi dei pulsanti sono rispettivamente btnOK e btnCancel.

Implementazione del codice di supporto

Aprire la visualizzazione del codice per il form. Il controllo restituisce i dati raccolti all'host corrispondente generando l'evento personalizzato OnButtonClick. I dati sono contenuti nell'oggetto dell'argomento dell'evento. Nell'esempio di codice riportato di seguito viene illustrato l'evento e la dichiarazione delegate. Aggiungere il codice riportato di seguito al file di codice, al di sotto del codice generato dalla finestra di progettazione.

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

La classe MyControlEventArgs contiene le informazioni da restituire all'host. Aggiungere la classe indicata di seguito allo spazio dei nomi del form.

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
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; }
    }
}

Quando l'utente fa clic su OK o su Annulla, il gestore eventi Control.Click crea un oggetto MyControlEventArgs che contiene i dati e genera l'evento OnButtonClick. L'unica differenza tra i due gestori è la proprietà IsOK dell'argomento dell'evento. Questa proprietà consente all'host di determinare su quale pulsante è stato fatto clic. La proprietà è impostata su true per il pulsante OK e su false per il pulsante Annulla. Nell'esempio di codice riportato di seguito vengono illustrati i gestori dei due pulsanti. Aggiungere il codice riportato di seguito alla classe, collocandolo al di sotto dell'evento e della dichiarazione delegate illustrati nel primo esempio di codice di questa sezione.

    Private Sub OKButton_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 CancelButton_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
End Class
private void OKButton_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 CancelButton_Click(object sender, System.EventArgs e)
{
    MyControlEventArgs retvals = new MyControlEventArgs(false,
                                                         txtName.Text,
                                                         txtAddress.Text,
                                                         txtCity.Text,
                                                         txtState.Text,
                                                         txtZip.Text);
    OnButtonClick(this, retvals);
}

Assegnazione di un nome sicuro all'assembly e compilazione dell'assembly

Perché a questo assembly venga fatto riferimento in un'applicazione WPF, è necessario che abbia un nome sicuro. Per creare un nome sicuro, creare un file di chiave Sn.exe e aggiungerlo al file AssemblyInfo.cs del progetto.

  1. Aprire un prompt dei comandi di Visual Studio. Per effettuare tale operazione, fare clic sul pulsante Start e scegliere Programmi/Microsoft Visual Studio 2008/Visual Studio Tools/Prompt dei comandi di Visual Studio 2008. Viene avviata una finestra della console con le variabili di ambiente personalizzate.

  2. Al prompt dei comandi utilizzare il comando "cd" per passare alla cartella del progetto.

  3. Generare un file di chiave denominato MyControls.snk eseguendo il comando indicato.

    Sn.exe -k MyControls.snk
    
  4. Per includere il file di chiave nel progetto, fare clic con il pulsante destro del mouse sul nome del progetto in Esplora soluzioni e scegliere Proprietà per aprire la finestra di dialogo corrispondente. Fare clic sulla scheda Firma e immettere il nome del file di chiave.

  5. Compilare l'assembly. La compilazione creerà una DLL denominata MyControls.dll.

Implementazione dell'applicazione host con Windows Presentation Foundation

L'applicazione host WPF utilizza il controllo WindowsFormsHost per ospitare MyControl1. L'applicazione gestisce l'evento OnButtonClick per ricevere i dati dal controllo. Dispone inoltre di un insieme di pulsanti di opzione che consente di modificare alcune delle proprietà del controllo dalla pagina WPF. Nell'immagine riportata di seguito viene illustrata l'applicazione finita.

L'applicazione completa, con il controllo incorporato nella pagina Windows Presentation Foundation

Controllo incorporato in una pagina WPF

Creazione del progetto

Per avviare il progetto:

  1. Aprire Visual Studio e selezionare Nuovo progetto.

  2. Selezionare il modello Applicazione browser WPF.

  3. Assegnare al progetto il nome WpfHost e scegliere OK per aprirlo.

È inoltre necessario aggiungere un riferimento alla DLL che contiene MyControl1: Il modo più semplice di aggiungere il riferimento è il seguente.

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul nome del progetto, quindi aprire la finestra di dialogo Aggiungi riferimento.

  2. Fare clic sulla scheda Sfoglia e spostarsi nella cartella dell'output del controllo Windows Form. Per questo esempio la cartella è MyControls\bin\Debug.

  3. Selezionare la DLL che contiene il controllo e scegliere OK per aggiungerla all'elenco di riferimenti. Per Esempio di hosting di controlli Windows Form compositi in Windows Presentation Foundation questa DLL è denominata MyControls.dll.

  4. In Esplora soluzioni aggiungere un riferimento all'assembly WindowsFormsIntegration, denominato WindowsFormsIntegration.dll.

Implementazione del layout di base

L'interfaccia utente dell'applicazione host viene implementata in Page1.xaml. Questo file contiene il markup Extensible Application Markup Language (XAML) che definisce il layout di pagina e ospita il controllo Windows Form. La pagina è suddivisa in tre aree:

  • Il pannello Proprietà del controllo che contiene un insieme di pulsanti di opzione che si possono utilizzare per modificare diverse proprietà del controllo ospitato.

  • Il pannello Dati dal controllo che contiene numerosi elementi TextBlock che consentono di visualizzare i dati restituiti dal controllo ospitato.

  • Il controllo ospitato stesso.

Nell'esempio di codice riportato di seguito viene illustrato il codice di layout di base. Il codice di markup necessario per ospitare MyControl1 viene omesso da questo esempio, ma verrà esaminato più avanti. Sostituire il codice in Page1.xaml con quanto segue.

<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="Page1"
      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>
</Page>
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="WpfHost.Page1"
      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>
</Page>

Il primo elemento StackPanel contiene numerose serie di controlli RadioButton che consentono di modificare diverse proprietà predefinite del controllo ospitato. Tale elemento è seguito da un elemento WindowsFormsHost, che ospita MyControl1. L'elemento finale StackPanel contiene numerosi elementi TextBlock che consentono di visualizzare i dati restituiti dal controllo ospitato. L'ordine degli elementi e le impostazioni degli attributi Dock e Height consentono di incorporare il controllo ospitato nella pagina senza spazi o distorsioni.

Hosting del controllo

La versione modificata riportata di seguito dell'esempio di codice precedente punta l'attenzione sugli elementi necessari per ospitare MyControl1.

<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="Page1"
      xmlns:mcl="clr-namespace:MyControls;assembly=MyControls"
      Loaded="Init">


...


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


...


<WindowsFormsHost Name="wfh"
                 DockPanel.Dock="Top"
                 Height="300">
  <mcl:MyControl1 Name="mc"/>
</WindowsFormsHost>

L'attributo del mapping dello spazio dei nomi xmlns crea un riferimento allo spazio dei nomi MyControls che contiene il controllo ospitato. Questo mapping consente di rappresentare MyControl1 in XAML come <mcl:MyControl1>.

Due elementi dell'esempio di codice gestiscono l'hosting:

  • WindowsFormsHost rappresenta l'elemento WindowsFormsHost che consente di ospitare un controllo Windows Form in una pagina WPF.

  • mcl:MyControl1, che rappresenta MyControl1, viene aggiunto all'insieme figlio dell'elemento WindowsFormsHost. Di conseguenza, viene eseguito il rendering di questo controllo Windows Form come parte della pagina WPF ed è possibile comunicare con il controllo dalla pagina.

Implementazione del file code-behind

Il file code-behind, Page1.xaml.cs, contiene il codice procedurale che implementa la funzionalità dell'interfaccia utente esaminata nella sezione precedente. Le attività principali sono:

  • Associare un gestore eventi all'evento OnButtonClick di MyControl1.

  • Modificare diverse proprietà di MyControl1, in base al modo in cui viene impostato l'insieme di pulsanti di opzione.

  • Visualizzare i dati raccolti dal controllo.

Inizializzazione dell'applicazione

Il codice di inizializzazione è contenuto in un gestore eventi per l'evento Loaded della pagina e associa un gestore eventi all'evento OnButtonClick del controllo. Copiare il codice riportato di seguito nella classe Page1 in Page1.xaml.cs.

Class Page1
    Inherits Page

    Private app As Application
    Private myWindow As NavigationWindow
    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, NavigationWindow)
        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
public partial class Page1 : Page
{
    private Application app;
    private NavigationWindow 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 = (NavigationWindow)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;
    }

Dato che il codice XAML esaminato in precedenza ha consentito di aggiungere MyControl1 all'insieme di elementi figlio dell'elemento WindowsFormsHost, è possibile eseguire il cast di Child dell'elemento WindowsFormsHost per ottenere il riferimento a MyControl1. È quindi possibile utilizzare tale riferimento per associare un gestore eventi a OnButtonClick.

Oltre a fornire un riferimento al controllo stesso, WindowsFormsHost espone numerose proprietà del controllo, che si possono manipolare dalla pagina. Il codice di inizializzazione assegna tali valori a variabili globali private per un uso successivo nell'applicazione.

Gestione dell'evento OnButtonClick

MyControl1 genera l'evento OnButtonClick quando l'utente fa clic su uno dei pulsanti del controllo. Aggiungere il codice riportato di seguito alla classe Page1.

    '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
End Class
//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 );
    }
}

I dati nelle caselle di testo vengono compressi nell'oggettoMyControlEventArgs. Se l'utente fa clic sul pulsante OK, il gestore eventi estrae i dati e li visualizza nel pannello sottostante a MyControl1.

Modifica delle proprietà del controllo

L'elemento WindowsFormsHost espone numerose proprietà predefinite del controllo ospitato. Di conseguenza è possibile modificare l'aspetto del controllo perché corrisponda più da vicino allo stile della pagina. Le serie di pulsanti di opzione del pannello sinistro consentono all'utente di modificare numerose proprietà del colore e del carattere. Ogni serie di pulsanti dispone di un gestore per l'evento Click, che rileva le selezioni del pulsante di opzione da parte dell'utente e modifica la proprietà corrispondente nel controllo. Copiare il codice riportato di seguito nella classe Page1. A questo punto è possibile compilare ed eseguire l'applicazione.

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
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;
}

Vedere anche

Attività

Procedura dettagliata: hosting di controlli Windows Form in Windows Presentation Foundation

Concetti

Procedura dettagliata: hosting di controlli di Windows Presentation Foundation in Windows Form

Riferimenti

ElementHost

WindowsFormsHost

Altre risorse

Progettazione WPF