Udostępnij za pośrednictwem


Wskazówki: Hosting złożonego formantu WPF w Windows Forms

Program Windows Presentation Foundation (WPF) udostępnia bogate środowisko do tworzenia aplikacji. Jednak jeśli masz znaczną inwestycję w kod Windows Forms, bardziej skuteczne może być rozszerzenie istniejącej aplikacji Windows Forms za pomocą WPF, a nie ponownego zapisania go od podstaw. Typowy scenariusz polega na tym, że chcesz osadzić co najmniej jedną kontrolkę zaimplementowaną za pomocą platformy WPF w aplikacji Windows Forms. Aby uzyskać więcej informacji na temat dostosowywania kontrolek WPF, zobacz Dostosowywanie kontrolek.

Ten przewodnik przeprowadzi Cię przez aplikację, która hostuje kontrolkę złożoną WPF w celu wykonania wpisu danych w aplikacji Windows Forms. Kontrolka złożona jest spakowana w dll. Ta ogólna procedura może zostać rozszerzona na bardziej złożone aplikacje i mechanizmy kontroli. Ten przewodnik został zaprojektowany tak, aby był niemal identyczny w wyglądzie i funkcjonalności w przewodniku: hostowanie kontrolki złożonej formularzy systemu Windows w WPF. Podstawową różnicą jest to, że scenariusz hostingu jest odwrócony.

Przewodnik jest podzielony na dwie sekcje. Pierwsza sekcja krótko opisuje implementację złożonej kontrolki WPF. W drugiej sekcji omówiono szczegółowo sposób hostowania złożonej kontrolki w aplikacji Windows Forms, odbierania zdarzeń z kontrolki i uzyskiwania dostępu do niektórych właściwości kontrolki.

Zadania przedstawione w tym przewodniku obejmują:

  • Implementowanie kontrolki złożonej WPF.

  • Implementowanie aplikacji hosta windows Forms.

Aby uzyskać pełną listę kodu zadań przedstawionych w tym przewodniku, zobacz Hosting a WPF Composite Control in Windows Forms Sample (Hostowanie kontrolki złożonej WPF w przykładzie formularzy systemu Windows).

Wymagania wstępne

Aby ukończyć ten przewodnik, potrzebny jest program Visual Studio.

Implementowanie kontrolki złożonej WPF

Kontrolka złożona WPF używana w tym przykładzie to prosty formularz wprowadzania danych, który przyjmuje nazwę i adres użytkownika. Gdy użytkownik kliknie jeden z dwóch przycisków, aby wskazać, że zadanie zostało zakończone, kontrolka zgłasza zdarzenie niestandardowe, aby zwrócić te informacje do hosta. Na poniższej ilustracji przedstawiono renderowaną kontrolkę.

Na poniższej ilustracji przedstawiono kontrolkę złożoną WPF:

Screenshot that shows a simple WPF control.

Tworzenie projektu

Aby rozpocząć projekt:

  1. Uruchom program Visual Studio i otwórz okno dialogowe Nowy projekt .

  2. W języku Visual C# i kategorii Systemu Windows wybierz szablon Biblioteka kontroli użytkownika WPF.

  3. Nadaj nowej nazwie nowy projekt MyControls.

  4. W przypadku lokalizacji określ wygodnie nazwany folder najwyższego poziomu, taki jak WindowsFormsHostingWpfControl. Później aplikacja hosta zostanie umieszczona w tym folderze.

  5. Kliknij przycisk OK, aby utworzyć projekt. Projekt domyślny zawiera pojedynczą kontrolkę o nazwie UserControl1.

  6. W Eksplorator rozwiązań zmień nazwę UserControl1 na MyControl1.

Projekt powinien zawierać odwołania do następujących bibliotek DLL systemu. Jeśli którakolwiek z tych bibliotek DLL nie jest domyślnie dołączona, dodaj je do projektu.

  • Rdzeń prezentacji

  • Element PresentationFramework

  • System

  • Windowsbase

Tworzenie interfejsu użytkownika

Interfejs użytkownika dla kontrolki złożonej jest implementowany za pomocą języka XAML (Extensible Application Markup Language). Interfejs użytkownika kontrolki złożonej składa się z pięciu TextBox elementów. Każdy TextBox element ma skojarzony TextBlock element, który służy jako etykieta. W dolnej części znajdują się dwa Button elementy: OK i Anuluj. Gdy użytkownik kliknie dowolny przycisk, kontrolka zgłasza zdarzenie niestandardowe, aby zwrócić informacje do hosta.

Układ podstawowy

Różne elementy interfejsu użytkownika są zawarte w elemecie Grid . Możesz użyć Grid polecenia , aby rozmieścić zawartość kontrolki złożonej w taki sam sposób, jak w Table języku HTML. WPF ma Table również element, ale Grid jest bardziej lekki i lepiej nadaje się do prostych zadań układu.

Poniższy kod XAML przedstawia podstawowy układ. Ten kod XAML definiuje ogólną strukturę kontrolki, określając liczbę kolumn i wierszy w elemecie Grid .

W pliku MyControl1.xaml zastąp istniejący kod XAML następującym kodem XAML.

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

Dodawanie elementów TextBlock i TextBox do siatki

Element interfejsu użytkownika można umieścić w siatce, ustawiając atrybuty RowProperty i ColumnProperty elementu na odpowiedni numer wiersza i kolumny. Pamiętaj, że numerowanie wierszy i kolumn jest oparte na zera. Element może obejmować wiele kolumn, ustawiając jego ColumnSpanProperty atrybut. Aby uzyskać więcej informacji na temat Grid elementów, zobacz Tworzenie elementu siatki.

Poniższy kod XAML przedstawia elementy i TextBlock kontrolki TextBox złożonej z ich RowProperty atrybutami iColumnProperty, które są ustawione tak, aby poprawnie umieścić elementy w siatce.

W pliku MyControl1.xaml dodaj następujący kod XAML w elemecie 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"/>

Stylowanie elementów interfejsu użytkownika

Wiele elementów w formularzu wprowadzania danych ma podobny wygląd, co oznacza, że mają identyczne ustawienia dla kilku ich właściwości. Zamiast ustawiać atrybuty każdego elementu oddzielnie, poprzedni kod XAML używa Style elementów do definiowania standardowych ustawień właściwości dla klas elementów. Takie podejście zmniejsza złożoność kontrolki i umożliwia zmianę wyglądu wielu elementów za pomocą pojedynczego atrybutu stylu.

Style Elementy są zawarte we Grid właściwości elementuResources, więc mogą być używane przez wszystkie elementy w kontrolce. Jeśli styl ma nazwę, należy zastosować go do elementu, dodając Style element ustawiony na nazwę stylu. Style, które nie są nazwane, stają się domyślnym stylem elementu. Aby uzyskać więcej informacji na temat stylów WPF, zobacz Styling and Templating (Styling and Templating).

Poniższy kod XAML przedstawia Style elementy kontrolki złożonej. Aby zobaczyć, jak style są stosowane do elementów, zobacz poprzedni kod XAML. Na przykład ostatni TextBlock element ma inlineText styl, a ostatni TextBox element używa stylu domyślnego.

W pliku MyControl1.xaml dodaj następujący kod XAML tuż po elemecie startowym 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>

Dodawanie przycisków OK i Anuluj

Ostatnimi elementami kontrolki złożonej są elementy OK i CancelButton, które zajmują dwie pierwsze kolumny ostatniego wiersza .Grid Te elementy używają typowej procedury obsługi zdarzeń, ButtonClickedi domyślnego Button stylu zdefiniowanego w poprzednim języku XAML.

W pliku MyControl1.xaml dodaj następujący kod XAML po ostatnim TextBox elemecie. Część XAML kontrolki złożonej została ukończona.

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

Implementowanie pliku za pomocą kodu

Plik za kodem MyControl1.xaml.cs implementuje trzy podstawowe zadania:

  1. Obsługuje zdarzenie, które występuje, gdy użytkownik kliknie jeden z przycisków.

  2. Pobiera dane z TextBox elementów i pakuje je w niestandardowym obiekcie argumentu zdarzenia.

  3. Zgłasza zdarzenie niestandardowe OnButtonClick , które powiadamia hosta o zakończeniu pracy użytkownika i przekazuje dane z powrotem do hosta.

Kontrolka uwidacznia również wiele właściwości koloru i czcionki, które umożliwiają zmianę wyglądu. WindowsFormsHost W przeciwieństwie do klasy, która jest używana do hostowania kontrolki Windows Forms, ElementHost klasa uwidacznia tylko właściwość kontrolkiBackground. Aby zachować podobieństwo między tym przykładem kodu a przykładem omówionymi w przewodniku: hostowanie kontrolki złożonej formularzy systemu Windows w WPF, kontrolka uwidacznia pozostałe właściwości bezpośrednio.

Podstawowa struktura pliku za pomocą kodu

Plik związany z kodem składa się z jednej przestrzeni nazw, MyControlsktóra będzie zawierać dwie klasy MyControl1 i MyControlEventArgs.

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

Pierwsza klasa, MyControl1, jest klasą częściową zawierającą kod, który implementuje funkcjonalność interfejsu użytkownika zdefiniowanego w pliku MyControl1.xaml. Po przeanalizowaniu pliku MyControl1.xaml kod XAML jest konwertowany na tę samą klasę częściową, a dwie klasy częściowe są scalane w celu utworzenia skompilowanej kontrolki. Z tego powodu nazwa klasy w pliku za kodem musi być zgodna z nazwą klasy przypisaną do pliku MyControl1.xaml i musi dziedziczyć z elementu głównego kontrolki. Druga klasa, MyControlEventArgs, to klasa argumentów zdarzeń używana do wysyłania danych z powrotem do hosta.

Otwórz plik MyControl1.xaml.cs. Zmień istniejącą deklarację klasy, aby ma następującą nazwę i dziedziczyła z Gridklasy .

public partial class MyControl1 : Grid

Inicjowanie kontrolki

Poniższy kod implementuje kilka podstawowych zadań:

  • Deklaruje zdarzenie prywatne, OnButtonClick, i skojarzony z nim delegat, MyControlEventHandler.

  • Tworzy kilka prywatnych zmiennych globalnych, które przechowują dane użytkownika. Te dane są udostępniane za pośrednictwem odpowiednich właściwości.

  • Implementuje program obsługi , Initdla zdarzenia kontrolki Loaded . Ta procedura obsługi inicjuje zmienne globalne, przypisując im wartości zdefiniowane w pliku MyControl1.xaml. W tym celu używa atrybutu przypisanego Name do typowego TextBlock elementu , nameLabelaby uzyskać dostęp do ustawień właściwości tego elementu.

Usuń istniejący konstruktor i dodaj następujący kod do klasy 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;
}

Obsługa zdarzeń kliknięcia przycisków

Użytkownik wskazuje, że zadanie wprowadzania danych zostało zakończone, klikając przycisk OK lub przycisk Anuluj . Oba przyciski używają tej samej Click procedury obsługi zdarzeń. ButtonClicked Oba przyciski mają nazwę btnOK lub btnCancel, która umożliwia programowi obsługi określenie, który przycisk został kliknięty, sprawdzając wartość argumentu sender . Procedura obsługi wykonuje następujące czynności:

  • Tworzy MyControlEventArgs obiekt zawierający dane z TextBox elementów.

  • Jeśli użytkownik kliknął przycisk Anuluj , ustaw MyControlEventArgs właściwość obiektu IsOK na false.

  • OnButtonClick Zgłasza zdarzenie, aby wskazać hostowi, że użytkownik jest gotowy, i przekazuje zebrane dane.

Dodaj następujący kod do MyControl1 klasy po metodzie 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);
}

Tworzenie właściwości

Pozostała część klasy po prostu uwidacznia właściwości, które odpowiadają wcześniej omówionych zmiennych globalnych. Gdy właściwość ulegnie zmianie, zestaw metod dostępu modyfikuje wygląd kontrolki, zmieniając odpowiednie właściwości elementu i aktualizując bazowe zmienne globalne.

Dodaj następujący kod do MyControl1 klasy.

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

Wysyłanie danych z powrotem do hosta

Ostatnim składnikiem w pliku jest MyControlEventArgs klasa, która służy do wysyłania zebranych danych z powrotem do hosta.

Dodaj następujący kod do MyControls przestrzeni nazw. Implementacja jest prosta i nie została omówiona dalej.

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

Stwórz rozwiązanie. Kompilacja utworzy bibliotekę DLL o nazwie MyControls.dll.

Implementowanie aplikacji hosta formularzy systemu Windows

Aplikacja hosta Windows Forms używa ElementHost obiektu do hostowania kontrolki złożonej WPF. Aplikacja obsługuje OnButtonClick zdarzenie w celu odbierania danych z kontrolki złożonej. Aplikacja ma również zestaw przycisków opcji, których można użyć do modyfikowania wyglądu kontrolki. Poniższa ilustracja przedstawia aplikację.

Na poniższej ilustracji przedstawiono kontrolkę złożoną WPF hostowaną w aplikacji Windows Forms

Screenshot that shows a Windows Form Hosting Avalon control.

Tworzenie projektu

Aby rozpocząć projekt:

  1. Uruchom program Visual Studio i otwórz okno dialogowe Nowy projekt .

  2. W języku Visual C# i kategorii Systemu Windows wybierz szablon Aplikacja formularzy systemu Windows.

  3. Nadaj nowej nazwie nowy projekt WFHost.

  4. W przypadku lokalizacji określ ten sam folder najwyższego poziomu, który zawiera projekt MyControls.

  5. Kliknij przycisk OK, aby utworzyć projekt.

Należy również dodać odwołania do biblioteki DLL zawierającej MyControl1 i inne zestawy.

  1. Kliknij prawym przyciskiem myszy nazwę projektu w Eksplorator rozwiązań, a następnie wybierz pozycję Dodaj odwołanie.

  2. Kliknij kartę Przeglądaj i przejdź do folderu zawierającego plik MyControls.dll. W tym przewodniku ten folder to MyControls\bin\Debug.

  3. Wybierz pozycję MyControls.dll, a następnie kliknij przycisk OK.

  4. Dodaj odwołania do następujących zestawów.

    • Rdzeń prezentacji

    • Element PresentationFramework

    • System.xaml

    • Windowsbase

    • WindowsFormsIntegration

Implementowanie interfejsu użytkownika dla aplikacji

Interfejs użytkownika aplikacji Formularz systemu Windows zawiera kilka kontrolek umożliwiających interakcję z kontrolką złożoną WPF.

  1. Otwórz formularz Form1 w Projektant formularza systemu Windows.

  2. Powiększ formularz, aby uwzględnić kontrolki.

  3. W prawym górnym rogu formularza dodaj kontrolkę System.Windows.Forms.Panel do przechowywania kontrolki złożonej WPF.

  4. Dodaj następujące System.Windows.Forms.GroupBox kontrolki do formularza.

    Nazwisko Tekst
    groupBox1 Kolor tła
    groupBox2 Kolor pierwszego planu
    groupBox3 Rozmiar czcionki
    groupBox4 Rodzina czcionek
    groupBox5 Styl czcionki
    groupBox6 Grubość czcionki
    groupBox7 Dane z kontrolki
  5. Dodaj następujące System.Windows.Forms.RadioButton kontrolki System.Windows.Forms.GroupBox do kontrolek.

    GroupBox Nazwisko Tekst
    groupBox1 radioBackgroundOriginal Oryginalne
    groupBox1 radioBackgroundLightGreen LightGreen
    groupBox1 radioBackgroundLightSalmon LightSalmon
    groupBox2 radioForegroundOriginal Oryginalne
    groupBox2 radioForegroundRed Czerwony
    groupBox2 radioForegroundYellow Yellow
    groupBox3 radioSizeOriginal Oryginalne
    groupBox3 radioSizeTen 10
    groupBox3 radioSizeTwelve 12
    groupBox4 radioFamilyOriginal Oryginalne
    groupBox4 radioFamilyTimes Times New Roman
    groupBox4 radioFamilyWingDings Wingdings
    groupBox5 radioStyleOriginal Normalna
    groupBox5 radioStyleItalic Italic
    groupBox6 radioWeightOriginal Oryginalne
    groupBox6 radioWeightBold Pogrubienie
  6. Dodaj następujące System.Windows.Forms.Label kontrolki do ostatniego System.Windows.Forms.GroupBoxelementu . Te kontrolki wyświetlają dane zwracane przez kontrolkę złożoną WPF.

    GroupBox Nazwisko Tekst
    groupBox7 lblName Nazwa:
    groupBox7 lblAddress Adres ulicy:
    groupBox7 lblCity City:
    groupBox7 lblState Stan:
    groupBox7 lblZip Zip:

Inicjowanie formularza

Zwykle implementujesz kod hostingu w procedurze obsługi zdarzeń formularza Load . Poniższy kod przedstawia procedurę Load obsługi zdarzeń, procedurę obsługi zdarzeń zdarzenia kontrolki Loaded złożonej WPF i deklaracje dla kilku zmiennych globalnych, które są używane później.

W Projektant formularzy systemu Windows kliknij dwukrotnie formularz, aby utworzyć procedurę obsługi zdarzeńLoad. W górnej części pliku Form1.cs dodaj następujące using instrukcje.

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

Zastąp zawartość istniejącej Form1 klasy następującym kodem.

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

Metoda Form1_Load w poprzednim kodzie przedstawia ogólną procedurę hostowania kontrolki WPF:

  1. Utwórz nowy ElementHost obiekt.

  2. Ustaw właściwość kontrolki Dock na DockStyle.Fill.

  3. Dodaj kontrolkę ElementHost do Panel kolekcji kontrolki Controls .

  4. Utwórz wystąpienie kontrolki WPF.

  5. Hostowanie złożonej kontrolki w formularzu przez przypisanie kontrolki do ElementHost właściwości kontrolki Child .

Pozostałe dwa wiersze w metodzie Form1_Load dołączają programy obsługi do dwóch zdarzeń sterujących:

  • OnButtonClick jest zdarzeniem niestandardowym wyzwalanym przez kontrolkę złożoną, gdy użytkownik kliknie przycisk OK lub Anuluj . Zdarzenie jest obsługiwane, aby uzyskać odpowiedź użytkownika i zebrać wszelkie dane określone przez użytkownika.

  • Loaded jest standardowym zdarzeniem zgłaszanym przez kontrolkę WPF, gdy jest w pełni załadowana. To zdarzenie jest używane tutaj, ponieważ przykład musi zainicjować kilka zmiennych globalnych przy użyciu właściwości z kontrolki. W momencie zdarzenia formularza Load kontrolka nie jest w pełni załadowana, a te wartości są nadal ustawione na nullwartość . Przed uzyskaniem dostępu do tych właściwości należy poczekać na wystąpienie zdarzenia kontrolki Loaded .

Procedura Loaded obsługi zdarzeń jest wyświetlana w poprzednim kodzie. Procedura OnButtonClick obsługi została omówiona w następnej sekcji.

Obsługa onButtonClick

Zdarzenie OnButtonClick występuje, gdy użytkownik kliknie przycisk OK lub Anuluj .

Procedura obsługi zdarzeń sprawdza pole argumentu IsOK zdarzenia, aby określić, który przycisk został kliknięty. Zmienne lbldanych odpowiadają kontrolkom Label , które zostały omówione wcześniej. Jeśli użytkownik kliknie przycisk OK , dane z kontrolek kontrolki TextBox są przypisywane do odpowiedniej Label kontrolki. Jeśli użytkownik kliknie przycisk Anuluj, Text wartości zostaną ustawione na ciągi domyślne.

Dodaj następujący przycisk, aby kliknąć kod procedury obsługi zdarzeń do Form1 klasy.

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

Skompiluj i uruchom aplikację. Dodaj tekst w kontrolce złożonej WPF, a następnie kliknij przycisk OK. Tekst zostanie wyświetlony w etykietach. W tym momencie kod nie został dodany do obsługi przycisków radiowych.

Modyfikowanie wyglądu kontrolki

Kontrolki RadioButton w formularzu umożliwią użytkownikowi zmianę pierwszego planu i kolorów tła kontrolki złożonej WPF, a także kilka właściwości czcionki. Kolor tła jest uwidaczniony przez ElementHost obiekt . Pozostałe właściwości są widoczne jako właściwości niestandardowe kontrolki.

Kliknij dwukrotnie każdą RadioButton kontrolkę w formularzu, aby utworzyć CheckedChanged programy obsługi zdarzeń. Zastąp programy obsługi zdarzeń CheckedChanged następującym kodem.

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

Skompiluj i uruchom aplikację. Kliknij różne przyciski radiowe, aby zobaczyć wpływ na kontrolkę złożoną WPF.

Zobacz też