Compartilhar via


Passo a passo: hospedando um controle composto do WPF nos Windows Forms

O WPF (Windows Presentation Foundation) fornece um ambiente avançado para a criação de aplicativos. No entanto, quando você tem um investimento substancial no código do Windows Forms, pode ser mais eficaz estender seu aplicativo existente do Windows Forms com o WPF em vez de reescrevê-lo do zero. Um cenário comum é quando você deseja inserir um ou mais controles implementados com o WPF em seu aplicativo Windows Forms. Para obter mais informações sobre como personalizar controles do WPF, consulte Control Customization.

Este passo a passo percorre um aplicativo que hospeda um controle composto do WPF para executar a entrada de dados em um aplicativo do Windows Forms. O controle composto é empacotado em uma DLL. Esse procedimento geral pode ser estendido para aplicativos e controles mais complexos. Este passo a passo foi elaborado para ser praticamente idêntico em aparência e funcionalidade ao Passo a passo: hospedando um controle composto do Windows Forms no WPF. A principal diferença é que o cenário de hospedagem é invertido.

O passo a passo é dividido em duas seções. A primeira seção descreve brevemente a implementação do controle composto do WPF. A segunda seção discute detalhadamente como hospedar o controle composto em um aplicativo do Windows Forms, receber eventos do controle e acessar algumas das propriedades do controle.

As tarefas ilustradas neste passo a passo incluem:

  • Implementando o controle composto do WPF.

  • Implementando o aplicativo host do Windows Forms.

Para uma listagem completa de código das tarefas ilustradas neste passo a passo, consulte o exemplo de Hospedagem de um Controle Composto WPF no Windows Forms.

Pré-requisitos

Você precisa do Visual Studio para concluir este passo a passo.

Implementando o controle composto do WPF

O controle de composição do WPF usado neste exemplo é um formulário de entrada de dados simples que usa o nome e o endereço do usuário. Quando o usuário clica em um dos dois botões para indicar que a tarefa foi concluída, o controle aciona um evento personalizado para retornar essas informações ao host. A ilustração a seguir mostra o controle renderizado.

A imagem a seguir mostra um controle composto do WPF:

Captura de tela que mostra um controle WPF simples.

Criando o projeto

Para iniciar o projeto:

  1. Inicie o Visual Studio e abra a caixa de diálogo Novo Projeto.

  2. No Visual C# e na categoria do Windows, selecione o modelo Biblioteca de controle de usuário do WPF.

  3. Nomeie o novo projeto MyControls.

  4. Para o local, especifique uma pasta de nível superior que tenha um nome conveniente, como WindowsFormsHostingWpfControl. Posteriormente, você colocará o aplicativo host nessa pasta.

  5. Clique em OK para criar o projeto. O projeto padrão contém um único controle chamado UserControl1.

  6. No Gerenciador de Soluções, renomeie UserControl1 para MyControl1.

Seu projeto deve ter referências às DLLs do sistema a seguir. Se qualquer uma dessas DLLs não estiver incluída por padrão, adicione-as ao seu projeto.

  • PresentationCore

  • PresentationFramework

  • Sistema

  • WindowsBase

Criando a interface do usuário

A interface do usuário (interface do usuário) para o controle composto é implementada com XAML (Extensible Application Markup Language). A interface de usuário de controle composto consiste de cinco elementos TextBox. Cada elemento TextBox tem um elemento TextBlock associado que serve como um rótulo. Há dois elementos Button na parte inferior, OK e Cancelar. Quando o usuário clica em um dos botões, o controle aciona um evento personalizado para retornar as informações ao host.

Layout Básico

Os vários elementos de interface do usuário estão contidos em um elemento Grid. Você pode usar Grid para organizar o conteúdo do controle composto da mesma maneira que usaria um elemento Table em HTML. O WPF também tem um elemento Table, mas Grid é mais leve e mais adequado para tarefas de layout simples.

O XAML a seguir mostra o layout básico. Esse XAML define a estrutura geral do controle especificando o número de colunas e linhas no elemento Grid.

Em MyControl1.xaml, substitua o XAML existente pelo XAML a seguir.

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

Adicionando elementos TextBlock e TextBox ao Grid

Você coloca um elemento de interface do usuário na grade definindo os atributos RowProperty e ColumnProperty do elemento para o número de linha e coluna apropriados. Lembre-se de que a numeração de linhas e colunas são baseadas em zero. Você pode ter um elemento que abrange várias colunas definindo seu atributo ColumnSpanProperty. Para obter mais informações sobre elementos Grid, consulte Criar um Elemento de Grade.

O XAML a seguir mostra os elementos TextBox e TextBlock do controle composto com seus atributos RowProperty e ColumnProperty, que são definidos para colocar os elementos corretamente na grade.

Em MyControl1.xaml, adicione o XAML a seguir dentro do 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"/>

Estilização dos elementos da interface de usuário

Muitos dos elementos no formulário de entrada de dados têm uma aparência semelhante, o que significa que eles têm configurações idênticas para várias de suas propriedades. Em vez de definir os atributos de cada elemento separadamente, o XAML anterior usa elementos Style para definir as configurações de propriedade padrão para classes de elementos. Essa abordagem reduz a complexidade do controle e permite que você altere a aparência de vários elementos por meio de um único atributo de estilo.

Os elementos Style estão contidos na propriedade Grid do elemento Resources, para que possam ser usados por todos os elementos no controle. Se um estilo for nomeado, você o aplicará a um elemento adicionando um elemento Style definido ao nome do estilo. Estilos que não são nomeados tornam-se o estilo padrão para o elemento. Para obter mais informações sobre estilos do WPF, consulte Estilo e Modelagem.

O XAML a seguir mostra os elementos Style para o controle composto. Para ver como os estilos são aplicados aos elementos, consulte o XAML anterior. Por exemplo, o último elemento TextBlock tem o estilo inlineText e o último elemento TextBox usa o estilo padrão.

Em MyControl1.xaml, adicione o XAML a seguir logo após o elemento de início 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>

Adicionando os botões OK e Cancel

Os elementos finais no controle composto são os elementos OK e CancelarButton, que ocupam as duas primeiras colunas da última linha do Grid. Esses elementos usam um manipulador de eventos comum, ButtonClickede o estilo de Button padrão definido no XAML anterior.

Em MyControl1.xaml, adicione o XAML a seguir após o último elemento TextBox. A parte XAML do controle composto agora está concluída.

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

Implementando o arquivo Code-Behind

O arquivo code-behind, MyControl1.xaml.cs, implementa três tarefas essenciais:

  1. Manipula o evento que ocorre quando o usuário clica em um dos botões.

  2. Recupera os dados dos elementos TextBox e os empacota em um objeto de argumento de evento personalizado.

  3. Aciona o evento OnButtonClick personalizado, que notifica o host de que o usuário terminou e passa os dados de volta para o host.

O controle também expõe várias propriedades de cor e fonte que permitem alterar a aparência. Ao contrário da classe WindowsFormsHost, que é usada para hospedar um controle do Windows Forms, a classe ElementHost expõe apenas a propriedade Background do controle. Para manter a similaridade entre este exemplo de código e o exemplo discutido em Passo a passo: hospedando um controle composto do Windows Forms emWPF, o controle expõe diretamente as propriedades restantes.

A estrutura básica do arquivo Code-Behind

O arquivo code-behind consiste em um único namespace, MyControls, que conterá duas classes, MyControl1 e MyControlEventArgs.

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

A primeira classe, MyControl1, é uma classe parcial que contém o código que implementa a funcionalidade da interface do usuário definida em MyControl1.xaml. Quando MyControl1.xaml é analisado, o XAML é convertido na mesma classe parcial e as duas classes parciais são mescladas para formar o controle compilado. Por esse motivo, o nome da classe no arquivo code-behind deve corresponder ao nome de classe atribuído a MyControl1.xaml e deve herdar do elemento raiz do controle. A segunda classe, MyControlEventArgs, é uma classe de argumentos de evento que é usada para enviar os dados de volta para o host.

Abra MyControl1.xaml.cs. Altere a declaração de classe existente para que ela tenha o nome a seguir e herda de Grid.

public partial class MyControl1 : Grid

Inicializando o controle

O código a seguir implementa várias tarefas básicas:

  • Declara um evento privado, OnButtonClick, e o respectivo delegado associado, MyControlEventHandler.

  • Cria várias variáveis globais privadas que armazenam os dados do usuário. Esses dados são expostos por meio de propriedades correspondentes.

  • Implementa um manipulador, Init, para o evento Loaded do controle. Esse manipulador inicializa as variáveis globais atribuindo-lhes os valores definidos em MyControl1.xaml. Para fazer isso, ele usa o Name atribuído a um elemento TextBlock típico, nameLabel, para acessar as configurações de propriedade desse elemento.

Exclua o construtor existente e adicione o código a seguir à 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;
}

Manipulando os eventos de clique dos botões

O usuário indica que a tarefa de entrada de dados foi concluída clicando no botão OK ou no botão Cancelar. Ambos os botões usam o mesmo manipulador de eventos Click, ButtonClicked. Ambos os botões têm um nome, btnOK ou btnCancel, que permite que o manipulador determine qual botão foi clicado examinando o valor do argumento sender. O manipulador faz o seguinte:

  • Cria um objeto MyControlEventArgs que contém os dados dos elementos TextBox.

  • Se o usuário clicou no botão Cancelar, define a propriedade MyControlEventArgs do objeto IsOK como false.

  • Gera o evento OnButtonClick para indicar ao host que o usuário terminou, e passa de volta os dados coletados.

Adicione o código a seguir à classe MyControl1, após o método 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);
}

Criando propriedades

O restante da classe simplesmente expõe propriedades que correspondem às variáveis globais discutidas anteriormente. Quando uma propriedade é alterada, o acessador de conjunto modifica a aparência do controle alterando as propriedades de elemento correspondentes e atualizando as variáveis globais subjacentes.

Adicione o código a seguir à sua 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;
    }
}

Enviando os dados de volta para o host

O componente final no arquivo é a classe MyControlEventArgs, que é usada para enviar os dados coletados de volta para o host.

Adicione o código a seguir ao namespace MyControls. A implementação é simples e não é discutida mais adiante.

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

Crie a solução. A compilação produzirá uma DLL chamada MyControls.dll.

Implementando o aplicativo host do Windows Forms

O aplicativo host do Windows Forms usa um objeto ElementHost para hospedar o controle composto do WPF. O aplicativo manipula o evento OnButtonClick para receber os dados do controle composto. O aplicativo também tem um conjunto de botões de opção que você pode usar para modificar a aparência do controle. A ilustração a seguir mostra o aplicativo.

A imagem a seguir mostra um controle composto do WPF hospedado em um aplicativo do Windows Forms

Captura de tela que mostra um controle Avalon hospedado em Windows Forms.

Criando o projeto

Para iniciar o projeto:

  1. Inicie o Visual Studio e abra a caixa de diálogo Novo Projeto.

  2. No Visual C# e na categoria do Windows, selecione o modelo Aplicativo do Windows Forms.

  3. Nomeie o novo projeto WFHost.

  4. Para o local, especifique a mesma pasta de nível superior que contém o projeto MyControls.

  5. Clique em OK para criar o projeto.

Você também precisa adicionar referências à DLL que contém MyControl1 e outros assemblies.

  1. Clique com o botão direito do mouse no nome do projeto no Gerenciador de Soluções e selecione Adicionar Referência.

  2. Clique na guia Procurar e navegue até a pasta que contém MyControls.dll. Para este passo a passo, essa pasta é MyControls\bin\Debug.

  3. Selecione MyControls.dlle clique em OK.

  4. Adicione referências aos assemblies a seguir.

    • PresentationCore

    • PresentationFramework

    • System.Xaml

    • WindowsBase

    • WindowsFormsIntegration

Implementando a interface do usuário para o aplicativo

A interface do usuário do aplicativo Windows Form contém vários controles para interagir com o controle composto do WPF.

  1. Abra o Form1 no Designer de Formulários do Windows.

  2. Amplie o formulário para acomodar os controles.

  3. No canto superior direito do formulário, adicione um controle identificado por System.Windows.Forms.Panel para suportar o controle composto do WPF.

  4. Adicione os controles System.Windows.Forms.GroupBox a seguir ao formulário.

    Nome Texto
    groupBox1 Cor da tela de fundo
    groupBox2 Cor do primeiro plano
    groupBox3 Tamanho da fonte
    groupBox4 Família de Fontes
    groupBox5 Estilo de fonte
    groupBox6 Peso da fonte
    groupBox7 Dados do controle
  5. Adicione os controles de System.Windows.Forms.RadioButton a seguir aos controles System.Windows.Forms.GroupBox.

    GroupBox Nome Texto
    groupBox1 fundoOriginalRádio Original
    groupBox1 botãoDeOpçãoFundoVerdeClaro Verde Claro
    groupBox1 radioBackgroundLightSalmon LightSalmon
    groupBox2 radioForegroundOriginal Original
    groupBox2 radioForegroundRed Vermelho
    groupBox2 radioForegroundYellow Amarelo
    groupBox3 tamanhoOriginalDoRádio Original
    groupBox3 radioSizeTen 10
    groupBox3 radioSizeTwelve 12
    groupBox4 radioFamíliaOriginal Original
    groupBox4 Rádio Family Times Times New Roman
    groupBox4 radioFamilyWingDings Wingdings
    groupBox5 radioStyleOriginal Normal
    groupBox5 radioStyleItalic Itálico
    groupBox6 radioWeightOriginal Original
    groupBox6 radioWeightBold Ousado
  6. Adicione os seguintes controles System.Windows.Forms.Label ao último System.Windows.Forms.GroupBox. Esses controles exibem os dados retornados pelo controle composto do WPF.

    GroupBox Nome Texto
    groupBox7 lblName Nome:
    groupBox7 lblEndereço Endereço de rua:
    groupBox7 lblCity Cidade:
    groupBox7 lblState Estado:
    groupBox7 lblZip CEP:

Inicializando o formulário

Geralmente, você implementa o código de hospedagem no manipulador de eventos Load do formulário. O código a seguir mostra o manipulador de eventos Load, um manipulador para o evento Loaded do controle composto do WPF e declarações para várias variáveis globais que são usadas posteriormente.

No Designer de Formulários do Windows, clique duas vezes no formulário para criar um manipulador de eventos Load. Na parte superior do Form1.cs, adicione as instruções using a seguir.

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

Substitua o conteúdo da classe Form1 existente pelo código a seguir.

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

O método Form1_Load no código anterior mostra o procedimento geral para hospedar um controle WPF:

  1. Crie um novo objeto ElementHost.

  2. Defina a propriedade Dock do controle como DockStyle.Fill.

  3. Adicione o controle ElementHost à coleção Panel do controle Controls.

  4. Crie uma instância do controle WPF.

  5. Hospede o controle composto no formulário atribuindo o controle à propriedade ElementHost do controle Child.

As duas linhas restantes no método Form1_Load anexam manipuladores a dois eventos de controle:

  • OnButtonClick é um evento personalizado que é acionado pelo controle composto quando o usuário clica no botão OK ou Cancelar. Você manipula o evento para obter a resposta do usuário e coletar todos os dados especificados pelo usuário.

  • Loaded é um evento padrão gerado por um controle WPF quando ele é totalmente carregado. O evento é usado aqui porque o exemplo precisa inicializar várias variáveis globais usando propriedades do controle. No momento do evento Load do formulário, o controle não é totalmente carregado e esses valores ainda estão definidos como null. Você precisa aguardar até que o evento Loaded do controle ocorra antes de poder acessar essas propriedades.

O manipulador de eventos Loaded é mostrado no código anterior. O manipulador de OnButtonClick será discutido na próxima seção.

Manipulando o OnButtonClick

O evento OnButtonClick ocorre quando o usuário clica no botão OK ou Cancelar.

O manipulador de eventos verifica o campo IsOK do argumento de evento para determinar qual botão foi clicado. As variáveis de de dados correspondem aos controles de discutidos anteriormente. Se o usuário clicar no botão OK, os dados dos controles de TextBox do controle serão atribuídos ao controle Label correspondente. Se o usuário clicar em Cancelar, os valores Text serão definidos como cadeias de caracteres padrão.

Adicione o código do manipulador de eventos de clique do botão a seguir à 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: ";
    }
}

Crie e execute o aplicativo. Adicione um pouco de texto no controle composto do WPF e clique em OK. O texto é exibido nos rótulos. Neste ponto, não foi adicionado um código para manipular os botões de opção.

Modificando a aparência do controle

Os controles de RadioButton no formulário permitirão que o usuário altere as cores de primeiro plano e plano de fundo do controle composto do WPF, bem como várias propriedades de fonte. A cor da tela de fundo é exposta pelo objeto ElementHost. As propriedades restantes são expostas como propriedades personalizadas do controle.

Clique duas vezes em cada controle RadioButton no formulário para criar manipuladores de eventos CheckedChanged. Substitua os manipuladores de eventos CheckedChanged pelo código a seguir.

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

Crie e execute o aplicativo. Clique nos diferentes botões de rádio para visualizar o efeito no controle composto do WPF.

Consulte também