Condividi tramite


Procedura dettagliata: Hosting di un controllo composito WPF in Windows Form

Windows Presentation Foundation (WPF) offre un ambiente avanzato per la creazione di applicazioni. Tuttavia, quando si ha un notevole investimento nel codice Windows Form, può essere più efficace estendere l'applicazione Windows Form esistente con WPF anziché riscriverla da zero. Uno scenario comune è quando si desidera incorporare uno o più controlli implementati con WPF all'interno dell'applicazione Windows Form. Per altre informazioni sulla personalizzazione dei controlli WPF, vedere Personalizzazione del controllo.

Questa procedura dettagliata illustra un'applicazione che ospita un controllo composito WPF per eseguire l'immissione di dati in un'applicazione Windows Form. Il controllo composito è incluso in una DLL. Questa procedura generale può essere estesa a applicazioni e controlli più complessi. Questa procedura dettagliata è progettata per essere quasi identica nell'aspetto e nella funzionalità di Procedura dettagliata: Hosting di un controllo composito di Windows Forms in WPF. La differenza principale è che lo scenario di hosting è invertito.

La procedura dettagliata è suddivisa in due sezioni. La prima sezione descrive brevemente l'implementazione del controllo composito WPF. La seconda sezione illustra in dettaglio come ospitare il controllo composito in un'applicazione Windows Form, ricevere eventi dal controllo e accedere ad alcune proprietà del controllo.

Le attività illustrate in questa procedura dettagliata includono:

  • Implementazione del controllo composito WPF.

  • Implementazione dell'applicazione host di Windows Forms.

Per l'elenco completo del codice delle attività illustrate in questa procedura dettagliata, vedere Esempio di Hosting di un Controllo Composito WPF in Windows Form.

Prerequisiti

Per completare questa procedura dettagliata, è necessario Visual Studio.

Implementazione del controllo composito WPF

Il controllo composito WPF usato in questo esempio è un modulo di immissione dati semplice che accetta il nome e l'indirizzo dell'utente. Quando l'utente fa clic su uno dei due pulsanti per indicare che l'attività è stata completata, il controllo genera un evento personalizzato per restituire tali informazioni all'host. L'illustrazione seguente mostra il controllo renderizzato.

L'immagine seguente mostra un controllo composito WPF:

Screenshot che mostra un semplice controllo WPF.

Creazione del progetto

Per avviare il progetto:

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

  2. Nella categoria Windows e in Visual C#, selezionare il modello libreria di controllo utente WPF.

  3. Assegnare al nuovo progetto il nome MyControls.

  4. Per la posizione, specificare una cartella di primo livello denominata in modo pratico, ad esempio WindowsFormsHostingWpfControl. Successivamente, l'applicazione host verrà inserita in questa cartella.

  5. Fare clic su OK per creare il progetto. Il progetto predefinito contiene un singolo controllo denominato UserControl1.

  6. In Esplora Soluzioni, rinominare UserControl1 in MyControl1.

Il progetto deve avere riferimenti alle DLL di sistema seguenti. Se una di queste DLL non è inclusa per impostazione predefinita, aggiungerle al progetto.

  • PresentationCore

  • PresentationFramework

  • Sistema

  • WindowsBase

Creazione dell'interfaccia utente

L'interfaccia utente per il controllo composito viene implementata con Extensible Application Markup Language (XAML). L'interfaccia utente del controllo composito è costituita da cinque elementi TextBox. Ogni elemento TextBox ha un elemento TextBlock associato che funge da etichetta. Nella parte inferiore sono presenti due elementi Button, OK e Cancel. Quando l'utente fa clic su uno dei due pulsanti, il controllo genera un evento personalizzato per restituire le informazioni all'host.

Layout di base

I vari elementi dell'interfaccia utente sono contenuti in un elemento Grid. È possibile usare Grid per disporre il contenuto del controllo composito nello stesso modo in cui si userebbe un elemento Table in HTML. WPF ha anche un elemento Table, ma Grid è più leggero e più adatto per attività di layout semplici.

Il codice XAML seguente mostra il layout di base. Questo codice XAML definisce la struttura complessiva del controllo specificando il numero di colonne e righe nell'elemento Grid.

In MyControl1.xaml sostituire il codice XAML esistente con il codice XAML seguente.

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="MyControls.MyControl1"
      Background="#DCDCDC"
      Width="375"
      Height="250"
      Name="rootElement"
      Loaded="Init">

  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition Width="Auto"/>
    <ColumnDefinition Width="Auto"/>
  </Grid.ColumnDefinitions>

  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>
</Grid>

Aggiunta di elementi TextBlock e TextBox alla griglia

Inserisci un elemento dell'interfaccia utente nella griglia impostando gli attributi RowProperty e ColumnProperty dell'elemento sul numero di riga e colonna appropriato. Tenere presente che la numerazione di righe e colonne è in base zero. È possibile avere un elemento che si estende su più colonne impostandone l'attributo ColumnSpanProperty. Per altre informazioni sugli elementi Grid, vedere Creare un elemento grid.

Il codice XAML seguente mostra gli elementi TextBox e TextBlock del controllo composito con i relativi attributi RowProperty e ColumnProperty, che vengono impostati per posizionare correttamente gli elementi nella griglia.

In MyControl1.xaml aggiungere il codice XAML seguente all'interno dell'elemento Grid.

  <TextBlock Grid.Column="0"
        Grid.Row="0" 
        Grid.ColumnSpan="4"
        Margin="10,5,10,0"
        HorizontalAlignment="Center"
        Style="{StaticResource titleText}">Simple WPF Control</TextBlock>

  <TextBlock Grid.Column="0"
        Grid.Row="1"
        Style="{StaticResource inlineText}"
        Name="nameLabel">Name</TextBlock>
  <TextBox Grid.Column="1"
        Grid.Row="1"
        Grid.ColumnSpan="3"
        Name="txtName"/>

  <TextBlock Grid.Column="0"
        Grid.Row="2"
        Style="{StaticResource inlineText}"
        Name="addressLabel">Street Address</TextBlock>
  <TextBox Grid.Column="1"
        Grid.Row="2"
        Grid.ColumnSpan="3"
        Name="txtAddress"/>

  <TextBlock Grid.Column="0"
        Grid.Row="3"
        Style="{StaticResource inlineText}"
        Name="cityLabel">City</TextBlock>
  <TextBox Grid.Column="1"
        Grid.Row="3"
        Width="100"
        Name="txtCity"/>

  <TextBlock Grid.Column="2"
        Grid.Row="3"
        Style="{StaticResource inlineText}"
        Name="stateLabel">State</TextBlock>
  <TextBox Grid.Column="3"
        Grid.Row="3"
        Width="50"
        Name="txtState"/>

  <TextBlock Grid.Column="0"
        Grid.Row="4"
        Style="{StaticResource inlineText}"
        Name="zipLabel">Zip</TextBlock>
  <TextBox Grid.Column="1"
        Grid.Row="4"
        Width="100"
        Name="txtZip"/>

Applicazione di stili agli elementi dell'interfaccia utente

Molti degli elementi nel modulo di immissione dati hanno un aspetto simile, il che significa che hanno impostazioni identiche per diverse delle relative proprietà. Anziché impostare separatamente gli attributi di ogni elemento, il codice XAML precedente usa Style elementi per definire le impostazioni delle proprietà standard per le classi di elementi. Questo approccio riduce la complessità del controllo e consente di modificare l'aspetto di più elementi tramite un singolo attributo di stile.

Gli elementi Style sono contenuti nella proprietà Resources dell'elemento Grid, in modo che possano essere utilizzati da tutti gli elementi del controllo. Se uno stile è denominato, lo si applica a un elemento aggiungendo un elemento Style impostato sul nome dello stile. Gli stili non denominati diventano lo stile predefinito per l'elemento. Per ulteriori informazioni sugli stili WPF, vedere Stili e modelli.

Il codice XAML seguente mostra gli elementi Style per il controllo composito. Per vedere come vengono applicati gli stili agli elementi, vedi il codice XAML precedente. Ad esempio, l'ultimo elemento TextBlock ha lo stile inlineText e l'ultimo elemento TextBox usa lo stile predefinito.

In MyControl1.xaml aggiungere il codice XAML seguente subito dopo l'elemento iniziale Grid.

<Grid.Resources>
  <Style x:Key="inlineText" TargetType="{x:Type TextBlock}">
    <Setter Property="Margin" Value="10,5,10,0"/>
    <Setter Property="FontWeight" Value="Normal"/>
    <Setter Property="FontSize" Value="12"/>
  </Style>
  <Style x:Key="titleText" TargetType="{x:Type TextBlock}">
    <Setter Property="DockPanel.Dock" Value="Top"/>
    <Setter Property="FontWeight" Value="Bold"/>
    <Setter Property="FontSize" Value="14"/>
    <Setter Property="Margin" Value="10,5,10,0"/>
  </Style>
  <Style TargetType="{x:Type Button}">
    <Setter Property="Margin" Value="10,5,10,0"/>
    <Setter Property="Width" Value="60"/>
  </Style>
  <Style TargetType="{x:Type TextBox}">
    <Setter Property="Margin" Value="10,5,10,0"/>
  </Style>
</Grid.Resources>

Aggiunta dei pulsanti OK e Annulla

Gli elementi finali del controllo composito sono gli elementi OK e CancelButton, che occupano le prime due colonne dell'ultima riga del Grid. Questi elementi usano un gestore eventi comune, ButtonClickede lo stile di Button predefinito definito nel codice XAML precedente.

In MyControl1.xaml aggiungere il codice XAML seguente dopo l'ultimo elemento TextBox. La parte XAML del controllo composito è ora completa.

<Button Grid.Row="5"
        Grid.Column="0"
        Name="btnOK"
        Click="ButtonClicked">OK</Button>
<Button Grid.Row="5"
        Grid.Column="1"
        Name="btnCancel"
        Click="ButtonClicked">Cancel</Button>

Implementazione del file Code-Behind

Il file code-behind, MyControl1.xaml.cs, implementa tre attività essenziali:

  1. Gestisce l'evento che si verifica quando l'utente fa clic su uno dei pulsanti.

  2. Recupera i dati dagli elementi TextBox e li inserisce in un oggetto argomento evento personalizzato.

  3. Genera l'evento personalizzato OnButtonClick, che notifica all'host che l'utente ha finito e restituisce i dati all'host.

Il controllo espone anche una serie di proprietà di colore e carattere che consentono di modificare l'aspetto. A differenza della classe WindowsFormsHost, utilizzata per ospitare un controllo Windows Form, la classe ElementHost espone solo la proprietà Background del controllo. Per mantenere la somiglianza tra questo esempio di codice e l'esempio descritto in Procedura dettagliata: Hosting di un controllo composito Windows Forms in WPF, il controllo espone direttamente le proprietà restanti.

Struttura di base del file Code-Behind

Il file code-behind è costituito da un singolo namespace MyControls, che conterrà due classi, MyControl1 e MyControlEventArgs.

namespace MyControls  
{  
  public partial class MyControl1 : Grid  
  {  
    //...  
  }  
  public class MyControlEventArgs : EventArgs  
  {  
    //...  
  }  
}  

La prima classe, MyControl1, è una classe parziale contenente il codice che implementa la funzionalità dell'interfaccia utente definita in MyControl1.xaml. Quando myControl1.xaml viene analizzato, il codice XAML viene convertito nella stessa classe parziale e le due classi parziali vengono unite per formare il controllo compilato. Per questo motivo, il nome della classe nel file code-behind deve corrispondere al nome della classe assegnato a MyControl1.xaml e deve ereditare dall'elemento radice del controllo. La seconda classe, MyControlEventArgs, è una classe di argomenti di evento usata per inviare i dati all'host.

Apri MyControl1.xaml.cs. Modificare la dichiarazione di classe esistente in modo che abbia il nome seguente ed eredita da Grid.

public partial class MyControl1 : Grid

Inizializzazione del controllo

Il codice seguente implementa diverse attività di base:

  • Dichiara un evento privato, OnButtonClicke il relativo delegato associato, MyControlEventHandler.

  • Crea diverse variabili globali private che archiviano i dati dell'utente. Questi dati vengono esposti tramite le proprietà corrispondenti.

  • Implementa un gestore, Init, per l'evento Loaded del controllo. Questo gestore inizializza le variabili globali assegnando loro i valori definiti in MyControl1.xaml. A tale scopo, usa il Name assegnato a un tipico elemento TextBlock, nameLabel, per accedere alle impostazioni delle proprietà di tale elemento.

Eliminare il costruttore esistente e aggiungere il codice seguente alla classe MyControl1.

public delegate void MyControlEventHandler(object sender, MyControlEventArgs args);
public event MyControlEventHandler OnButtonClick;
private FontWeight _fontWeight;
private double _fontSize;
private FontFamily _fontFamily;
private FontStyle _fontStyle;
private SolidColorBrush _foreground;
private SolidColorBrush _background;

private void Init(object sender, EventArgs e)
{
    //They all have the same style, so use nameLabel to set initial values.
    _fontWeight = nameLabel.FontWeight;
    _fontSize = nameLabel.FontSize;
    _fontFamily = nameLabel.FontFamily;
    _fontStyle = nameLabel.FontStyle;
    _foreground = (SolidColorBrush)nameLabel.Foreground;
    _background = (SolidColorBrush)rootElement.Background;
}

Gestione degli eventi Click dei pulsanti

L'utente indica che l'attività di immissione dati è stata completata cliccando sul pulsante OK oppure sul pulsante Annulla. Entrambi i pulsanti usano lo stesso gestore eventi Click, ButtonClicked. Entrambi i pulsanti hanno un nome, btnOK o btnCancel, che consente al gestore di determinare quale pulsante è stato selezionato esaminando il valore dell'argomento sender. Il gestore esegue le operazioni seguenti:

  • Crea un oggetto MyControlEventArgs che contiene i dati degli elementi TextBox.

  • Se l'utente ha fatto clic sul pulsante Annulla, imposta la proprietà IsOK dell'oggetto MyControlEventArgs su false.

  • Genera l'evento OnButtonClick per indicare all'host che l'utente è terminato e restituisce i dati raccolti.

Aggiungere il codice seguente alla classe MyControl1 dopo il metodo Init.

private void ButtonClicked(object sender, RoutedEventArgs e)
{
    MyControlEventArgs retvals = new MyControlEventArgs(true,
                                                        txtName.Text,
                                                        txtAddress.Text,
                                                        txtCity.Text,
                                                        txtState.Text,
                                                        txtZip.Text);
    if (sender == btnCancel)
    {
        retvals.IsOK = false;
    }
    if (OnButtonClick != null)
        OnButtonClick(this, retvals);
}

Creazione di proprietà

Il resto della classe espone semplicemente le proprietà che corrispondono alle variabili globali descritte in precedenza. Quando una proprietà viene modificata, la funzione di accesso set modifica l'aspetto del controllo modificando le proprietà dell'elemento corrispondenti e aggiornando le variabili globali sottostanti.

Aggiungere il codice seguente alla classe MyControl1.

public FontWeight MyControl_FontWeight
{
    get { return _fontWeight; }
    set
    {
        _fontWeight = value;
        nameLabel.FontWeight = value;
        addressLabel.FontWeight = value;
        cityLabel.FontWeight = value;
        stateLabel.FontWeight = value;
        zipLabel.FontWeight = value;
    }
}
public double MyControl_FontSize
{
    get { return _fontSize; }
    set
    {
        _fontSize = value;
        nameLabel.FontSize = value;
        addressLabel.FontSize = value;
        cityLabel.FontSize = value;
        stateLabel.FontSize = value;
        zipLabel.FontSize = value;
    }
}
public FontStyle MyControl_FontStyle
{
    get { return _fontStyle; }
    set
    {
        _fontStyle = value;
        nameLabel.FontStyle = value;
        addressLabel.FontStyle = value;
        cityLabel.FontStyle = value;
        stateLabel.FontStyle = value;
        zipLabel.FontStyle = value;
    }
}
public FontFamily MyControl_FontFamily
{
    get { return _fontFamily; }
    set
    {
        _fontFamily = value;
        nameLabel.FontFamily = value;
        addressLabel.FontFamily = value;
        cityLabel.FontFamily = value;
        stateLabel.FontFamily = value;
        zipLabel.FontFamily = value;
    }
}

public SolidColorBrush MyControl_Background
{
    get { return _background; }
    set
    {
        _background = value;
        rootElement.Background = value;
    }
}
public SolidColorBrush MyControl_Foreground
{
    get { return _foreground; }
    set
    {
        _foreground = value;
        nameLabel.Foreground = value;
        addressLabel.Foreground = value;
        cityLabel.Foreground = value;
        stateLabel.Foreground = value;
        zipLabel.Foreground = value;
    }
}

Invio dei dati all'host

Il componente finale nel file è la classe MyControlEventArgs, che viene usata per inviare nuovamente i dati raccolti all'host.

Aggiungi il codice seguente allo spazio dei nomi MyControls. L'implementazione è semplice e non viene discussa ulteriormente.

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

Creare la soluzione. La compilazione genererà una DLL denominata MyControls.dll.

Implementazione dell'applicazione host Windows Forms

L'applicazione host Windows Form usa un oggetto ElementHost per ospitare il controllo composito WPF. L'applicazione gestisce l'evento OnButtonClick per ricevere i dati dal controllo composito. L'applicazione include anche un set di pulsanti di opzione che è possibile usare per modificare l'aspetto del controllo. La figura seguente illustra l'applicazione.

L'immagine seguente mostra un controllo composito WPF ospitato in un'applicazione Windows Form

Screenshot che mostra un Windows Form che ospita un controllo Avalon.

Creazione del progetto

Per avviare il progetto:

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

  2. In Visual C# e nella categoria Windows, selezionare il modello applicazione Windows Forms.

  3. Assegnare al nuovo progetto il nome WFHost.

  4. Per il percorso, specificare la stessa cartella di primo livello che contiene il progetto MyControls.

  5. Fare clic su OK per creare il progetto.

È inoltre necessario aggiungere riferimenti alle DLL che contengono MyControl1 e altri assembly.

  1. Fare clic con il pulsante destro del mouse sul nome del progetto in Esplora soluzioni e selezionare Aggiungi riferimento.

  2. Fare clic sulla scheda Sfoglia e passare alla cartella contenente MyControls.dll. Per questa procedura dettagliata, questa cartella è MyControls\bin\Debug.

  3. Selezionare MyControls.dlle quindi fare clic su OK.

  4. Aggiungere riferimenti agli assembly seguenti.

    • PresentationCore

    • PresentationFramework

    • System.Xaml

    • WindowsBase

    • WindowsFormsIntegration

Implementazione dell'interfaccia utente per l'applicazione

L'interfaccia utente per l'applicazione Windows Form contiene diversi controlli per interagire con il controllo composito WPF.

  1. aprire Form1 nel Designer di Windows Form.

  2. Ingrandire il modulo per ospitare i controlli.

  3. Nell'angolo in alto a destra del modulo, aggiungere un controllo System.Windows.Forms.Panel per ospitare il controllo composito WPF.

  4. Aggiungere i controlli System.Windows.Forms.GroupBox seguenti al modulo.

    Nome Testo
    groupBox1 Colore di sfondo
    groupBox2 Colore di primo piano
    groupBox3 Dimensioni carattere
    groupBox4 Famiglia di caratteri
    groupBox5 Stile del carattere
    groupBox6 Peso del carattere
    groupBox7 Dati dal controllo
  5. Aggiungere i controlli System.Windows.Forms.RadioButton seguenti ai controlli System.Windows.Forms.GroupBox.

    GroupBox Nome Testo
    groupBox1 radioSfondoOriginale Originale
    groupBox1 sfondoRadioVerdeChiaro Verde chiaro
    groupBox1 radioBackgroundLightSalmon LightSalmon
    groupBox2 radioIn primo pianoOriginale Originale
    groupBox2 radioForegroundRed Rosso
    groupBox2 radioForegroundYellow Giallo
    groupBox3 radioDimensioneOriginale Originale
    groupBox3 radioSizeTen 10
    groupBox3 radioSizeTwelve 12
    groupBox4 radioFamilyOriginal Originale
    groupBox4 radioFamilyTimes Times New Roman
    groupBox4 radioFamilyWingDings Wingdings
    groupBox5 radioStyleOriginal Normale
    groupBox5 radioStyleItalic Corsivo
    groupBox6 radioWeightOriginal Originale
    groupBox6 radioWeightBold Audace
  6. Aggiungere i seguenti controlli di System.Windows.Forms.Label all'ultimo System.Windows.Forms.GroupBox. Questi controlli visualizzano i dati restituiti dal controllo composito WPF.

    GroupBox Nome Testo
    groupBox7 lblNome Nome:
    groupBox7 lblIndirizzo Indirizzo:
    groupBox7 lblCity Città:
    groupBox7 lblStato Stato:
    groupBox7 lblZip Zip:

Inizializzazione del modulo

In genere si implementa il codice di hosting nel gestore eventi Load del modulo. Il codice seguente illustra il gestore eventi Load, un gestore per l'evento Loaded del controllo composito WPF e le dichiarazioni per diverse variabili globali usate in un secondo momento.

Nel Designer di Windows Form, fare doppio-clic sul modulo per creare un gestore eventi Load. Nella parte superiore di Form1.cs aggiungere le istruzioni using seguenti.

using System.Windows;
using System.Windows.Forms.Integration;
using System.Windows.Media;

Sostituire il contenuto della classe Form1 esistente con il codice seguente.

private ElementHost ctrlHost;
private MyControls.MyControl1 wpfAddressCtrl;
System.Windows.FontWeight initFontWeight;
double initFontSize;
System.Windows.FontStyle initFontStyle;
System.Windows.Media.SolidColorBrush initBackBrush;
System.Windows.Media.SolidColorBrush initForeBrush;
System.Windows.Media.FontFamily initFontFamily;

public Form1()
{
    InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
    ctrlHost = new ElementHost();
    ctrlHost.Dock = DockStyle.Fill;
    panel1.Controls.Add(ctrlHost);
    wpfAddressCtrl = new MyControls.MyControl1();
    wpfAddressCtrl.InitializeComponent();
    ctrlHost.Child = wpfAddressCtrl;

    wpfAddressCtrl.OnButtonClick +=
        new MyControls.MyControl1.MyControlEventHandler(
        avAddressCtrl_OnButtonClick);
    wpfAddressCtrl.Loaded += new RoutedEventHandler(
        avAddressCtrl_Loaded);
}

void avAddressCtrl_Loaded(object sender, EventArgs e)
{
    initBackBrush = (SolidColorBrush)wpfAddressCtrl.MyControl_Background;
    initForeBrush = wpfAddressCtrl.MyControl_Foreground;
    initFontFamily = wpfAddressCtrl.MyControl_FontFamily;
    initFontSize = wpfAddressCtrl.MyControl_FontSize;
    initFontWeight = wpfAddressCtrl.MyControl_FontWeight;
    initFontStyle = wpfAddressCtrl.MyControl_FontStyle;
}

Il metodo Form1_Load nel codice precedente mostra la procedura generale per l'hosting di un controllo WPF:

  1. Creare un nuovo oggetto ElementHost.

  2. Impostare la proprietà Dock del controllo su DockStyle.Fill.

  3. Aggiungere il controllo ElementHost alla raccolta Controls del controllo Panel.

  4. Creare un'istanza del controllo WPF.

  5. Ospitare il controllo composito nel form assegnando il controllo alla proprietà Child del controllo ElementHost.

Le due righe rimanenti del metodo Form1_Load collegano gestori a due eventi di controllo:

  • OnButtonClick è un evento personalizzato generato dal controllo composito quando l'utente fa clic sul pulsante OK o Annulla. L'evento viene gestito per ottenere la risposta dell'utente e per raccogliere i dati specificati dall'utente.

  • Loaded è un evento standard generato da un controllo WPF quando viene caricato completamente. L'evento viene usato qui perché l'esempio deve inizializzare diverse variabili globali usando le proprietà del controllo . Al momento dell'evento Load del modulo, il controllo non è completamente caricato e quei valori sono ancora impostati su null. È necessario attendere che si verifichi l'evento Loaded del controllo prima di poter accedere a tali proprietà.

Il gestore eventi Loaded viene visualizzato nel codice precedente. Il gestore OnButtonClick viene illustrato nella sezione successiva.

Gestione di OnButtonClick

L'evento OnButtonClick si verifica quando l'utente fa clic sul pulsante OK o Annulla.

Il gestore eventi controlla il campo IsOK dell'argomento evento per determinare quale pulsante è stato premuto. Le variabili di dati lbl corrispondono ai controlli Label discussi in precedenza. Se l'utente fa clic sul pulsante OK, i dati dei controlli TextBox del controllo vengono assegnati al controllo Label corrispondente. Se l'utente fa clic Annulla, i valori di Text vengono impostati sulle stringhe predefinite.

Aggiungi il seguente codice del gestore eventi clic per il pulsante alla classe Form1.

void avAddressCtrl_OnButtonClick(
    object sender,
    MyControls.MyControl1.MyControlEventArgs args)
{
    if (args.IsOK)
    {
        lblAddress.Text = "Street Address: " + args.MyStreetAddress;
        lblCity.Text = "City: " + args.MyCity;
        lblName.Text = "Name: " + args.MyName;
        lblState.Text = "State: " + args.MyState;
        lblZip.Text = "Zip: " + args.MyZip;
    }
    else
    {
        lblAddress.Text = "Street Address: ";
        lblCity.Text = "City: ";
        lblName.Text = "Name: ";
        lblState.Text = "State: ";
        lblZip.Text = "Zip: ";
    }
}

Compilare ed eseguire l'applicazione. Aggiungere testo nel controllo composito WPF e quindi fare clic su OK. Il testo viene visualizzato nelle etichette. A questo punto, non è stato aggiunto il codice necessario per gestire i pulsanti di opzione.

Modifica dell'aspetto del controllo

I controlli RadioButton nel form consentiranno all'utente di modificare i colori di primo piano e di sfondo del controllo composito WPF, nonché diverse proprietà del tipo di carattere. Il colore di sfondo viene esposto dall'oggetto ElementHost. Le proprietà rimanenti vengono esposte come proprietà personalizzate del controllo.

Fare doppio clic su ogni controllo RadioButton nel form per creare CheckedChanged gestori di eventi. Sostituire i gestori di eventi CheckedChanged con il codice seguente.

private void radioBackgroundOriginal_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_Background = initBackBrush;
}

private void radioBackgroundLightGreen_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_Background = new SolidColorBrush(Colors.LightGreen);
}

private void radioBackgroundLightSalmon_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_Background = new SolidColorBrush(Colors.LightSalmon);
}

private void radioForegroundOriginal_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_Foreground = initForeBrush;
}

private void radioForegroundRed_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_Foreground = new System.Windows.Media.SolidColorBrush(Colors.Red);
}

private void radioForegroundYellow_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_Foreground = new System.Windows.Media.SolidColorBrush(Colors.Yellow);
}

private void radioFamilyOriginal_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontFamily = initFontFamily;
}

private void radioFamilyTimes_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontFamily = new System.Windows.Media.FontFamily("Times New Roman");
}

private void radioFamilyWingDings_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontFamily = new System.Windows.Media.FontFamily("WingDings");
}

private void radioSizeOriginal_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontSize = initFontSize;
}

private void radioSizeTen_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontSize = 10;
}

private void radioSizeTwelve_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontSize = 12;
}

private void radioStyleOriginal_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontStyle = initFontStyle;
}

private void radioStyleItalic_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontStyle = System.Windows.FontStyles.Italic;
}

private void radioWeightOriginal_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontWeight = initFontWeight;
}

private void radioWeightBold_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontWeight = FontWeights.Bold;
}

Compilare ed eseguire l'applicazione. Fare clic sui diversi pulsanti di opzione per vedere l'effetto sui controlli compositi di WPF.

Vedere anche