Partilhar via


Demonstra Passo a passo: Hospedagem de um controle composto do Windows Forms no Windows Presentation Foundation

Windows Presentation Foundation (WPF) provides a rich environment for creating applications. No entanto, quando você tiver um investimento significativo em código Windows Forms, pode ser mais eficiente reutilizar pelo menos parte desse código em seu aplicativo WPF em vez de reescrevê-lo a partir do zero. A situação mais comum é quando você tem controles Windows Forms personalizados existentes. Em alguns casos, talvez você não ainda tenha acesso ao código-fonte para esses controles. WPF Fornece um procedimento simples para hospedar esses controles em um WPF aplicativo. Por exemplo, você pode usar WPF para a maioria da sua programação enquanto hospeda seus controles System.Windows.Forms.DataGridView especializados.

Essa explicação passo a passo exemplifica um aplicativo que hospeda um controle Windows Forms composto em uma página WPF. Esse procedimento geral pode ser estendido para aplicativos e controles mais complexos.

A explicação passo a passo é dividida em duas seções. A primeira seção rapidamente descreve a implementação do controle Windows Forms. A segunda seção discute detalhadamente como hospedar a página em um aplicativo WPF, receber eventos a partir do controle, e acessar algumas das propriedades do controle.

Tarefas ilustradas nesta explicação passo a passo incluem:

  • Implementando o controle Windows Forms.

  • Implementando o aplicativo host com Windows Presentation Foundation.

For a complete code listing of the tasks illustrated in this walkthrough, see Hospedagem de um Controlarar composto do Windows Forms no Windows Presentation Foundation Exemplo.

Pré-requisitos

Para completar este passo a passo, são necessários os seguintes componentes:

  • Visual Studio 2008.

Implementando o controle Windows Forms.

O controle Windows Forms usado nesse exemplo é uma forma simples de entrada de dados. Este formulário recupera o nome e endereço do usuário e, em seguida, usa um evento personalizado para retornar estas informações para o host. A ilustração a seguir mostra o controle renderizado.

O controle Windows Forms

Controle simples do Window Forms

Criando o projeto

Para iniciar o projeto:

  1. Iniciar Microsoft Visual Studio e abrir a caixa de diálogo Novo Projeto.

  2. Selecione C# Projects com o modelo Biblioteca de controle Windows Forms.

  3. Atribua o nome MyControls ao projeto, e clique em OK para criar o projeto. O projeto padrão contém um único controle denominado UserControl1.

  4. Altere o nome de UserControl1 para MyControl1.

Seu projeto deve ter referências às seguintes DLLs de sistema. Se quaisquer dessas DLLs não forem incluídas por padrão, adicione-as ao seu projeto.

  • Sistema

  • System.Data

  • System.Drawing

  • System.Windows.Forms

  • System.XML

Adicionar os controles ao formulário

Para adicionar controles ao formulário:

  • Abra o designer para MyControl1.

Coloque seis controles System.Windows.Forms.Label e seus controles System.Windows.Forms.TextBox correspondentes, dimensionados e organizados como estão na ilustração anterior, no formulário. No exemplo, os controles TextBox são nomeados:

  • txtName

  • txtAddress

  • txtCity

  • txtState

  • txtZip

Adicionar dois controles System.Windows.Forms.Button rotulados como OK e Cancelar. No exemplo, os nomes de botões são btnOK e btnCancel, respectivamente.

Implementando o código de suporte

Abrir a visão de código de formulário. O controle retorna os dados coletados para seu host, gerando o evento OnButtonClick personalizado. Os dados estão contidos no objeto do argumento do evento. O exemplo de código a seguir mostra a declaração do evento e do delegado. Adicione este código ao arquivo de código, abaixo do código gerado pelo designer.

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;

A classe MyControlEventArgs contém as informações a serem retornadas para o host. Adicione a seguinte classe ao namespace do formulário.

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 o usuário clica o botão OK ou Cancelar, os manipuladores de eventos Control.Click criam um objeto MyControlEventArgs que contém os dados e gera o evento OnButtonClick. A única diferença entre os dois manipuladores é a propriedade IsOK do argumento do evento. Essa propriedade permite que o host determine qual botão foi clicado. Ela é definida como true para o botão OK e false para o botão Cancelar. O exemplo de código a seguir mostra os dois manipuladores de botão. Adicione esse código à sua classe, colocando-o abaixo da declaração do evento e delegate mostrado no primeiro código de exemplo contido nesta seção.

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

Fornecendo um nome de alta segurança ao conjunto de módulos (assembly) e criando o conjunto de módulos (assembly)

Para este conjunto de módulos (assembly) ser referenciado por um aplicativo WPF, ele deve ter um nome forte. Para criar um nome forte, crie um arquivo de chave com Sn.exe e adicione-o ao arquivo AssemblyInfo.cs do seu projeto.

  1. Abra um prompt de comando Visual Studio. Para fazer isso, clique no menu Iniciar, e selecione Todos os Programas/Microsoft Visual Studio 2008/Ferramentas Visual Studio/Prompt de Comando Visual Studio 2008. Isso inicializa uma janela de console com variáveis de ambiente personalizadas.

  2. No prompt de comando, use o comando "cd" para ir para a pasta do projeto.

  3. Gerar um arquivo de chave chamado MyControls.snk, executando o comando a seguir.

    Sn.exe -k MyControls.snk
    
  4. Para incluir o arquivo de chave em seu projeto, clique com o botão direito do mouse no nome do projeto no Gerenciador de Soluções e abra a caixa de diálogo Propriedades. Selecione a guia Assinatura e digite o nome do arquivo de chave.

  5. Compile o conjunto de módulos (assembly). A compilação produzirá uma DLL denominada MyControls.dll.

Implementando o aplicativo host com Windows Presentation Foundation.

O aplicativo host WPF usa o controle WindowsFormsHost para hospedar MyControl1. O aplicativo manipula o evento OnButtonClick para receber os dados do controle. Ele também possui um conjunto de botões de opção que permitem que você altere algumas das propriedades do controle a partir da página WPF. A ilustração a seguir mostra o aplicativo concluído.

O aplicativo concluído, mostrar o controle incorporado à página Windows Presentation Foundation

Um controle inserido em uma página do WPF

Criando o projeto

Para iniciar o projeto:

  1. Abra Visual Studio e selecione Novo Projeto.

  2. Selecione o modelo Aplicativo de Navegação WPF.

  3. Nomeie o projeto WpfHost e clique em OK para abrir o projeto.

É necessário também adicionar uma referência para a DLL que contém MyControl1. A maneira mais simples de adicionar a referência é da seguinte maneira.

  1. Clique com o botão direito do mouse no nome do projeto no Gerenciador de Soluções, e inicie a caixa de diálogo Adicionar Referência.

  2. Clique na guia Navegar e vá para pasta de saída do controle Windows Form. Para esse exemplo, essa pasta é MyControls\bin\Debug.

  3. Selecione a DLL que contém o controle, e clique em OK para adicioná-la à lista de referências. Para Hospedagem de um Controlarar composto do Windows Forms no Windows Presentation Foundation Exemplo, essa DLL é denominada MyControls.dll.

  4. No Solution Explorer, acrescente uma referência ao assembly WindowsFormsIntegration, que é chamado WindowsFormsIntegration.dll.

Implementando o layout básico

O interface do usuário (UI) do aplicativo host é implementado em Page1.xaml. Esse arquivo contém marcação Extensible Application Markup Language (XAML) que define o layout da página e hospeda o controle Windows Forms. A página é dividida em três áreas:

  • O painel Propriedades do Controle, que contém uma coleção de botões de opção que você pode usar para modificar diversas propriedades do controle hospedado.

  • O painel Dados do controle, que contém vários elementos TextBlock que exibem os dados retornados a partir do controle hospedado.

  • O controle hospedado propriamente dito.

O código do layout básico é mostrado no exemplo de código a seguir. O código de marcação é necessário para hospedar MyControl1 é omitido neste exemplo, mas será abordado posteriormente. Substitua o código em Page1.xaml pelo seguinte.

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

O primeiro elemento StackPanel contém vários conjuntos de controles RadioButton que permitem que você modifique diversas propriedades padrão do controle hospedado. Ele é seguido por um elemento WindowsFormsHost, que hospeda MyControl1. O elemento StackPanel final contém vários elementos TextBlock que exibem os dados retornados pelo controle hospedado. A ordem dos elementos e as configurações de atributo Dock e Height incorporam o controle hospedado na página sem espaços ou distorção.

Hospedando o controle

A seguinte versão editada do exemplo de código anterior enfoca os elementos necessários para hospedar 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>

O atributo de mapeamento do namespace xmlns cria uma referência ao namespace MyControls que contém o controle hospedado. Esse mapeamento permite que você represente MyControl1 no XAML como <mcl:MyControl1>.

Dois elementos de exemplo de código manipulam a hospedagem:

  • WindowsFormsHost representa o elemento WindowsFormsHost que permite que você hospede um controle Windows Forms em uma página WPF.

  • mcl:MyControl1, que representa MyControl1, é adicionado à coleção filha do elemento WindowsFormsHost. Como resultado, esse controle Windows Forms é processado como parte da página WPF, e você pode se comunicar com o controle a partir da página.

Implementando o arquivo de código de lógica

O arquivo de código de lógica, Page1.xaml.cs, contém o código procedural que implementa a funcionalidade da UI discutida na seção anterior. As tarefas principais são:

  • Anexar um manipulador de eventos para o evento OnButtonClick de MyControl1.

  • Modificar diversas propriedades de MyControl1, baseado em como a coleção de botões de opção é definida.

  • Exibir os dados coletados pelo controle.

Inicializando o aplicativo

O código de inicialização está contido em um manipulador de eventos para o evento Loaded da página e anexa um manipulador de eventos ao evento OnButtonClick do controle. Copie o código a seguir para a classe Page1 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;
    }

Já que o código XAML discutido previamente adicionou MyControl1 à coleção do elemento filho do elemento WindowsFormsHost, você pode converter Child do elemento WindowsFormsHost para obter a referência a MyControl1. Em seguida, você pode usar essa referência para anexar um manipulador de eventos a OnButtonClick.

Além de fornecer uma referência ao controle em si, WindowsFormsHost expõe um número de propriedades do controle, que você pode manipular a partir da página. O código de inicialização atribui estes valores a variáveis globais privadas para uso posterior no aplicativo.

Manipulando o evento OnButtonClick

MyControl1 gera o evento OnButtonClick quando o usuário clica em um dos botões do controle. Adicione o código a seguir à sua 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 );
    }
}

Os dados nas caixas de texto são compactados dentro do objeto MyControlEventArgs. Se o usuário clica no botão OK, o manipulador de eventos extrai os dados e exibe-os no painel abaixo de MyControl1.

Modificando propriedades do controle

O elemento WindowsFormsHost expõe várias das propriedades padrão do controle hospedado. Como resultado, você pode alterar a aparência do controle para coincidir com o estilo da sua página. Os conjuntos de botões de opção no painel esquerdo permitem ao usuário modificar diversas propriedades de cores e fontes. Cada conjunto de botões tem um manipulador para o evento Click, que detecta seleções de botão de opção pelo usuário e altera a propriedade correspondente no controle. Copie o código a seguir à sua classe Page1. Agora já é possível compilar e executar o aplicativo.

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

Consulte também

Tarefas

Demonstra Passo a passo: Hospedagem de um controle de formulários do Windows no Windows Presentation Foundation

Conceitos

Demonstra Passo a passo: Hospedagem de um controle Windows Presentation Foundation no Windows Forms

Referência

ElementHost

WindowsFormsHost

Outros recursos

WPF Designer