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

O Windows Presentation Foundation (WPF) 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 reutilizar pelo menos parte desse código em seu aplicativo WPF em vez de reescrevê-lo do zero. O cenário mais comum é quando você tem controles existentes do Windows Forms. Em alguns casos, talvez você não tenha nem acesso ao código-fonte desses controles. O WPF fornece um procedimento simples para hospedar esses controles em um aplicativo WPF. Por exemplo, você pode usar o WPF para a maior parte de sua programação enquanto hospeda seus controles especializados DataGridView .

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

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

As tarefas ilustradas neste passo a passo incluem:

  • Implementação do controle de composição dos Windows Forms.

  • Implementação do aplicativo host do WPF.

Para uma listagem de código completa de todas as tarefas ilustradas neste passo a passo, consulte Exemplo de hospedagem de um controle de composição dos Windows Forms no WPF.

Pré-requisitos

É necessário o Visual Studio para concluir este passo a passo.

Implementação do controle de composição dos Windows Forms

O controle composto do Windows Forms usado neste exemplo é um formulário de entrada de dados simples. Este formulário recebe o nome e o endereço do usuário e, em seguida, usa um evento personalizado para retornar essa informação ao host. A ilustração a seguir mostra o controle renderizado.

A imagem a seguir mostra um controle composto do Windows Forms:

Screenshot that shows a simple Windows Forms control.

Criando o Projeto

Para iniciar o projeto:

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

  2. Na categoria Janela, selecione o modelo da Biblioteca de Controle Windows Forms.

  3. Dê um nome ao novo projeto MyControls.

  4. Para o local, especifique uma pasta de nível superior nomeada de forma conveniente, como WpfHostingWindowsFormsControl. Mais tarde, você colocará o aplicativo host nessa pasta.

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

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

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

  • Sistema

  • System.Data

  • System.Drawing

  • System.Windows.Forms

  • System.Xml

Adicionando controles ao formulário

Para adicionar controles ao formulário:

  • Abra MyControl1 no designer.

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

  • txtName

  • txtAddress

  • txtCity

  • txtState

  • txtZip

Adicione dois Button controles rotulados como OK e Cancelar. No exemplo, os nomes dos botões são btnOK e btnCancel, respectivamente.

Implementando o código de suporte

Abra o formulário no modo de exibição de código. O controle retorna os dados coletados para seu host gerando o evento personalizado OnButtonClick . Os dados estão contidos no objeto de argumento do evento. O código a seguir mostra a declaração do evento e do delegado.

Adicione o código a seguir à classe MyControl1 .

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

A MyControlEventArgs classe contém as informações a serem retornadas ao host.

Adicione a seguinte classe ao formulário.

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

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

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

Quando o usuário clica no botão OK ou Cancelar , os Click manipuladores de eventos criam um MyControlEventArgs objeto que contém os dados e gera o OnButtonClick evento. A única diferença entre os dois manipuladores é a propriedade do argumento de IsOK evento. Essa propriedade permite que o host determine qual botão foi clicado. Ele é definido como true para o botão OK e false para o botão Cancelar. O código a seguir mostra os dois manipuladores de botão.

Adicione o código a seguir à classe MyControl1 .

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

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

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

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

End Sub

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

End Sub

Fornecendo um nome forte e compilando o assembly

Para que esse assembly seja referenciado por um aplicativo WPF, ele deve ter um nome forte. Para criar um nome forte, crie um arquivo de chave com o Sn.exe e adicione-o ao seu projeto.

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

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

  3. Gere 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, em seguida, clique em Propriedades. No Designer de Projeto, clique na guia Assinatura, marque a caixa de seleção Assinar o assembly e, em seguida, navegue até o arquivo de chave.

  5. Compile a solução. O build produzirá uma DLL denominada MyControls.dll.

Implementação do aplicativo host do WPF

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

A imagem a seguir mostra o aplicativo completo, incluindo o controle incorporado no aplicativo WPF:

Screenshot that shows a control embedded in a WPF page.

Criando o Projeto

Para iniciar o projeto:

  1. Abra o Visual Studio e selecione Novo Projeto.

  2. Na categoria Janela, selecione o modelo Aplicativo WPF.

  3. Dê um nome ao novo projeto WpfHost.

  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 a MyControls.dll. Para este passo a passo, a pasta é a MyControls\bin\Debug.

  3. Selecione MyControls.dll e, em seguida, clique em OK.

  4. Adicione uma referência ao assembly WindowsFormsIntegration, que é chamado WindowsFormsIntegration.dll.

Implementando o layout básico

A interface do usuário (UI) do aplicativo host é implementada em MainWindow.xaml. Esse arquivo contém marcação XAML (Extensible Application Markup Language) que define o layout e hospeda o controle Windows Forms. O aplicativo é dividido em três regiões:

  • O painel de 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.

  • Os dados do painel de controle, que contém vários TextBlock elementos que exibem os dados retornados do controle hospedado.

  • O próprio controle hospedado.

O layout básico é mostrado no seguinte XAML. A marcação necessária para hospedar MyControl1 é omitida deste exemplo, mas será discutida posteriormente.

Substitua o XAML em MainWindow.xaml pelo seguinte. Se você estiver usando o Visual Basic, altere a classe para x:Class="MainWindow".

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

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

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

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

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

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

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

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

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

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

Hospedagem do controle

A seguinte versão editada do XAML anterior se concentra nos elementos necessários para hospedar o MyControl1.

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

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

Dois elementos no XAML manipulam a hospedagem:

  • WindowsFormsHost representa o WindowsFormsHost elemento que permite hospedar um controle do Windows Forms em um aplicativo WPF.

  • mcl:MyControl1, que representa MyControl1, é adicionado à WindowsFormsHost coleção filho do elemento. Como resultado, esse controle do Windows Forms é renderizado como parte da janela WPF e você pode se comunicar com o controle do aplicativo.

Implementando o arquivo code-behind

O arquivo code-behind, MainWindow.xaml.vb ou MainWindow.xaml.cs, contém o código de procedimento que implementa a funcionalidade da interface do usuário discutida na seção anterior. As tarefas principais são:

  • Anexando um manipulador de eventos ao MyControl1evento 's OnButtonClick .

  • Modificar diversas propriedades do 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 da Loaded janela e anexa um manipulador de eventos ao evento do OnButtonClick controle.

Em MainWindow.xaml.vb ou MainWindow.xaml.cs, adicione o seguinte código à MainWindow classe.

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

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


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

    Dim mc As MyControl1 = wfh.Child

    AddHandler mc.OnButtonClick, AddressOf Pane1_OnButtonClick
    UIIsReady = True

End Sub

Como o XAML discutido anteriormente foi adicionado MyControl1 à WindowsFormsHost coleção de elementos filho do elemento, você pode converter o WindowsFormsHost elemento para Child obter a referência a MyControl1. Você pode usar essa referência para anexar um manipulador de eventos ao OnButtonClick.

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

Para que você possa acessar facilmente os tipos na MyControls DLL, adicione a seguinte Imports instrução ou using à parte superior do arquivo.

Imports MyControls
using MyControls;

Manipulando o evento OnButtonClick

MyControl1 Gera o evento quando o OnButtonClick usuário clica em um dos botões do controle.

Adicione o código a seguir à classe MainWindow .

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

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

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

End Sub

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

Modificando as propriedades do controle

O WindowsFormsHost elemento expõe várias das propriedades padrão do controle hospedado. Como resultado, você pode alterar a aparência do controle para combinar melhor com o estilo do seu aplicativo. Os conjuntos de botões de opção no painel esquerdo permitem ao usuário modificar várias propriedades de fonte e cor. Cada conjunto de botões tem um manipulador para o Click evento, que detecta as seleções de botão de opção do usuário e altera a propriedade correspondente no controle.

Adicione o código a seguir à classe MainWindow .

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

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

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

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

End Sub

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

End Sub

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

End Sub

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

End Sub

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

End Sub

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

End Sub

Crie e execute o aplicativo. Adicione algum texto no controle de composição dos Windows Forms e, em seguida, clique em OK. O texto é exibido nos rótulos. Clique nos diferentes botões de opção para ver o efeito no controle.

Confira também