次の方法で共有


チュートリアル: Windows フォームでの WPF 複合コントロールのホスト

Windows Presentation Foundation (WPF) は、アプリケーションを作成するための豊富な環境を提供します。 ただし、Windows フォーム コードに多額の投資がある場合は、既存の Windows フォーム アプリケーションを最初から書き直すのではなく、WPF を使用して拡張する方が効果的です。 一般的なシナリオは、WPF で実装された 1 つ以上のコントロールを Windows フォーム アプリケーション内に埋め込む場合です。 WPF コントロールのカスタマイズの詳細については、「コントロールのカスタマイズ」を参照してください。

このチュートリアルでは、WINDOWS フォーム アプリケーションでデータ入力を実行する WPF 複合コントロールをホストするアプリケーションについて説明します。 複合コントロールは DLL にパッケージ化されています。 この一般的な手順は、より複雑なアプリケーションとコントロールに拡張できます。 このチュートリアルは、外観と機能が、WPFで Windows フォーム複合コントロールをホストする チュートリアルとほぼ同じに設計されています。 主な違いは、ホスティング シナリオが逆になっている点です。

このチュートリアルは、2 つのセクションに分かれています。 最初のセクションでは、WPF 複合コントロールの実装について簡単に説明します。 2 番目のセクションでは、Windows フォーム アプリケーションで複合コントロールをホストし、コントロールからイベントを受信し、コントロールのプロパティの一部にアクセスする方法について詳しく説明します。

このチュートリアルで説明するタスクは次のとおりです。

  • WPF 複合コントロールの実装。

  • Windows フォーム ホスト アプリケーションの実装。

このチュートリアルで示すタスクの完全なコード一覧については、「Windows フォームでの WPF 複合コントロールのホスト サンプル」を参照してください。

前提 条件

このチュートリアルを完了するには、Visual Studio が必要です。

WPF 複合コントロールの実装

この例で使用される WPF 複合コントロールは、ユーザーの名前とアドレスを受け取る単純なデータ入力フォームです。 ユーザーが 2 つのボタンのいずれかをクリックしてタスクが完了したことを示すと、コントロールはカスタム イベントを発生させ、その情報をホストに返します。 次の図は、レンダリングされたコントロールを示しています。

次の図は、WPF 複合コントロールを示しています。

単純な WPF コントロールを示すスクリーンショット。

プロジェクトの作成

プロジェクトを開始するには:

  1. Visual Studio を起動し、新しいプロジェクト ダイアログ ボックスを開きます。

  2. Visual C# と Windows カテゴリで、WPF ユーザー コントロール ライブラリ テンプレート を選択します。

  3. 新しいプロジェクトに MyControls名前を付けます。

  4. 場所には、WindowsFormsHostingWpfControlなど、便利な名前の最上位フォルダーを指定します。 後で、このフォルダーにホスト アプリケーションを配置します。

  5. [OK] をクリックしてプロジェクトを作成します。 既定のプロジェクトには、UserControl1という名前のコントロールが 1 つ含まれています。

  6. ソリューション エクスプローラーで、UserControl1 の名前を MyControl1に変更します。

プロジェクトには、次のシステム DLL への参照が必要です。 これらの DLL のいずれかが既定で含まれていない場合は、プロジェクトに追加します。

  • PresentationCore

  • PresentationFramework

  • システム

  • WindowsBase

ユーザー インターフェイスの作成

複合コントロールのユーザー インターフェイス (UI) は、Extensible Application Markup Language (XAML) を使用して実装されます。 複合コントロール UI は、5 つの TextBox 要素で構成されます。 各 TextBox 要素には、ラベルとして機能する TextBlock 要素が関連付けられています。 下部には 2 つの Button 要素があります。OKキャンセルです。 ユーザーがいずれかのボタンをクリックすると、コントロールはカスタム イベントを発生させ、情報をホストに返します。

基本レイアウト

さまざまな UI 要素は、Grid 要素に含まれています。 Grid を使用すると、HTML で Table 要素を使用するのとほぼ同じ方法で複合コントロールの内容を配置できます。 WPF には Table 要素もありますが、Grid は軽量で、単純なレイアウト タスクに適しています。

次の XAML は、基本的なレイアウトを示しています。 この XAML では、Grid 要素内の列と行の数を指定することで、コントロールの全体的な構造を定義します。

MyControl1.xaml で、既存の XAML を次の 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>

TextBlock 要素と TextBox 要素をグリッドに追加する

UI 要素をグリッドに配置するには、要素の RowProperty 属性と ColumnProperty 属性を適切な行と列の番号に設定します。 行番号と列番号は 0 から始まる点に注意してください。 ColumnSpanProperty 属性を設定することで、要素が複数の列にまたがるように設定できます。 Grid 要素の詳細については、「グリッド要素を作成する」を参照してください。

次の XAML は、複合コントロールの TextBox 要素と TextBlock 要素とその RowProperty 属性と ColumnProperty 属性を示しています。この属性は、要素をグリッドに適切に配置するように設定されています。

MyControl1.xaml で、Grid 要素内に次の XAML を追加します。

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

UI 要素のスタイル設定

データ入力フォームの要素の多くは外観が似ています。つまり、いくつかのプロパティに対して同じ設定が設定されています。 前の XAML では、各要素の属性を個別に設定するのではなく、Style 要素を使用して、要素のクラスの標準プロパティ設定を定義します。 この方法では、コントロールの複雑さが軽減され、1 つのスタイル属性を使用して複数の要素の外観を変更できます。

Style 要素は、Grid 要素の Resources プロパティに含まれているため、コントロール内のすべての要素で使用できます。 スタイルに名前が付けられている場合は、スタイルの名前に Style 要素セットを追加して、そのスタイルを要素に適用します。 名前のないスタイルは、要素の既定のスタイルになります。 WPF スタイルの詳細については、「スタイルとテンプレート」を参照してください。

次の XAML は、複合コントロールの Style 要素を示しています。 要素にスタイルがどのように適用されるかを確認するには、前の XAML を参照してください。 たとえば、最後の TextBlock 要素には inlineText スタイルがあり、最後の TextBox 要素は既定のスタイルを使用します。

MyControl1.xaml で、Grid 開始要素の直後に次の XAML を追加します。

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

[OK] ボタンと [キャンセル] ボタンの追加

複合コントロールの最後の要素は、OKCancelButton 要素です。これは、Gridの最後の行の最初の 2 つの列を占めます。 これらの要素は、共通のイベント ハンドラー、ButtonClicked、および前の XAML で定義された既定の Button スタイルを使用します。

MyControl1.xaml で、最後の TextBox 要素の後に次の XAML を追加します。 複合コントロールの XAML 部分が完成しました。

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

Code-Behind ファイルの実装

分離コード ファイル (MyControl1.xaml.cs) には、次の 3 つの重要なタスクが実装されています。

  1. ユーザーがいずれかのボタンをクリックしたときに発生するイベントを処理します。

  2. TextBox 要素からデータを取得し、カスタム イベント引数オブジェクトにパッケージ化します。

  3. カスタム OnButtonClick イベントを発生させ、ユーザーが完了したことをホストに通知し、データをホストに渡します。

コントロールには、外観を変更できる色とフォントのプロパティも多数公開されています。 Windows フォーム コントロールをホストするために使用される WindowsFormsHost クラスとは異なり、ElementHost クラスはコントロールの Background プロパティのみを公開します。 このコード例と、「チュートリアル: WPFでの Windows フォーム複合コントロールのホスト」で説明した例との類似性を維持するために、コントロールは残りのプロパティを直接公開します。

Code-Behind ファイルの基本的な構造

分離コード ファイルは、MyControl1MyControlEventArgsの 2 つのクラスを含む 1 つの名前空間 MyControlsで構成されます。

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

最初のクラス MyControl1は、MyControl1.xaml で定義されている UI の機能を実装するコードを含む部分クラスです。 MyControl1.xaml が解析されると、XAML は同じ部分クラスに変換され、2 つの部分クラスがマージされてコンパイルされたコントロールが形成されます。 このため、分離コード ファイル内のクラス名は MyControl1.xaml に割り当てられているクラス名と一致する必要があり、コントロールのルート要素から継承する必要があります。 2 番目のクラス MyControlEventArgsは、ホストにデータを送り返すために使用されるイベント引数クラスです。

MyControl1.xaml.csを開きます。 次の名前を持ち、Gridから継承するように、既存のクラス宣言を変更します。

public partial class MyControl1 : Grid

コントロールの初期化

次のコードは、いくつかの基本的なタスクを実装します。

  • プライベートイベント OnButtonClickと、それに関連するデリゲート MyControlEventHandlerを宣言します。

  • ユーザーのデータを格納する複数のプライベート グローバル変数を作成します。 このデータは、対応するプロパティを介して公開されます。

  • コントロールの Loaded イベントのハンドラー (Init) を実装します。 このハンドラーは、MyControl1.xaml で定義されている値を割り当てることで、グローバル変数を初期化します。 これを行うには、一般的な TextBlock 要素 (nameLabel) に割り当てられた Name を使用して、その要素のプロパティ設定にアクセスします。

既存のコンストラクターを削除し、次のコードを 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;
}

ボタンのクリック イベントの処理

ユーザーは、[OK] ボタンまたは [キャンセル] ボタンをクリックして、データ入力タスクが完了したことを示します。 どちらのボタンも同じClickイベントハンドラーButtonClickedを使用しています。 どちらのボタンにも名前 (btnOK または btnCancel) があります。これにより、ハンドラーは、sender 引数の値を調べることで、どのボタンがクリックされたかを判断できます。 ハンドラーは次の処理を行います。

  • TextBox 要素のデータを含む MyControlEventArgs オブジェクトを作成します。

  • ユーザーが [キャンセル] ボタンをクリックした場合は、MyControlEventArgs オブジェクトの IsOK プロパティを falseに設定します。

  • ユーザーが完了したことをホストに示す OnButtonClick イベントを発生させ、収集されたデータを返します。

Init メソッドの後に、MyControl1 クラスに次のコードを追加します。

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

プロパティの作成

クラスの残りの部分では、前に説明したグローバル変数に対応するプロパティを公開するだけです。 プロパティが変更されると、set アクセサーは、対応する要素プロパティを変更し、基になるグローバル変数を更新することで、コントロールの外観を変更します。

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

ホストへのデータの返送

ファイル内の最後のコンポーネントは、収集されたデータをホストに送り返すために使用される MyControlEventArgs クラスです。

MyControls 名前空間に次のコードを追加します。 実装は簡単であり、これ以上説明しません。

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

ソリューションをビルドします。 ビルドでは、MyControls.dllという名前の DLL が生成されます。

Windows フォーム ホスト アプリケーションの実装

Windows フォーム ホスト アプリケーションは、WPF 複合コントロールをホストするために ElementHost オブジェクトを使用します。 アプリケーションは、複合コントロールからデータを受信する OnButtonClick イベントを処理します。 アプリケーションには、コントロールの外観を変更するために使用できるオプション ボタンのセットもあります。 次の図は、アプリケーションを示しています。

次の図は、Windows フォーム アプリケーションでホストされている WPF 複合コントロールを示しています

Windows Forms の Avalon コントロールをホスティングしている様子を示すスクリーンショット。

プロジェクトの作成

プロジェクトを開始するには:

  1. Visual Studio を起動し、[新しいプロジェクト] ダイアログ ボックスを開きます。

  2. Visual C# と Windows カテゴリで、Windows フォーム アプリケーション テンプレートを選択します。

  3. 新しいプロジェクトに WFHost名前を付けます。

  4. この場所には、MyControls プロジェクトを含む同じ最上位フォルダーを指定します。

  5. [OK] をクリックしてプロジェクトを作成します

また、MyControl1 およびその他のアセンブリを含む DLL への参照を追加する必要があります。

  1. ソリューション エクスプローラーでプロジェクト名を右クリックし、[参照の追加]選択します。

  2. [参照] タブをクリックし、MyControls.dllを含むフォルダーを参照します。 このチュートリアルでは、このフォルダーは MyControls\bin\Debug です。

  3. [MyControls.dll] を選択し、[OK]クリックします。

  4. 次のアセンブリへの参照を追加します。

    • PresentationCore

    • PresentationFramework

    • System.Xaml

    • WindowsBase

    • WindowsFormsIntegration

アプリケーションのユーザー インターフェイスの実装

Windows フォーム アプリケーションの UI には、WPF 複合コントロールと対話するための複数のコントロールが含まれています。

  1. Windows フォーム デザイナーで Form1 を開きます。

  2. コントロールを収容できるようにフォームを拡大します。

  3. フォームの右上隅に、WPF 複合コントロールを保持する System.Windows.Forms.Panel コントロールを追加します。

  4. フォームに次の System.Windows.Forms.GroupBox コントロールを追加します。

    名前 テキスト
    グループボックス1 背景色
    groupBox2 前景色
    グループボックス3 フォント サイズ
    グループボックス4 フォント ファミリ
    groupBox5 フォント スタイル
    groupBox6 フォントの太さ
    groupBox7 コントロールからのデータ
  5. 次の System.Windows.Forms.RadioButton コントロールを System.Windows.Forms.GroupBox コントロールに追加します。

    GroupBox 名前 テキスト
    グループボックス1 ラジオ背景オリジナル オリジナル
    groupBox1 ラジオ背景ライトグリーン ライトグリーン
    グループボックス1 ラジオ背景ライトサーモン色 LightSalmon
    groupBox2 ラジオ前景オリジナル オリジナル
    グループボックス2 radioForegroundRed 赤い
    グループボックス2 radioForegroundYellow 黄色
    groupBox3 ラジオサイズオリジナル 翻訳元
    グループボックス3 radioSizeTen 10
    groupBox3 radioSizeTwelve 12
    グループボックス4 ラジオファミリーオリジナル オリジナル
    groupBox4 ラジオファミリータイムズ Times New Roman
    グループボックス4 ラジオファミリーウィングディングス WingDings
    groupBox5 ラジオスタイルオリジナル 正常
    groupBox5 イタリックラジオスタイル イタリック
    グループボックス6 radioWeightOriginal 翻訳元
    groupBox6 radioWeightBold ボールド
  6. 次の System.Windows.Forms.Label コントロールを最後の System.Windows.Forms.GroupBoxに追加します。 これらのコントロールには、WPF 複合コントロールによって返されるデータが表示されます。

    GroupBox 名前 テキスト
    groupBox7 lblName 名前:
    groupBox7 lblAddress 番地:
    groupBox7 lblCity 都市:
    グループボックス7 lblState 状態:
    groupBox7 lblZip 郵便番号

フォームの初期化

通常、フォームの Load イベント ハンドラーにホスティング コードを実装します。 次のコードは、Load イベント ハンドラー、WPF 複合コントロールの Loaded イベントのハンドラー、および後で使用するいくつかのグローバル変数の宣言を示しています。

Windows フォーム デザイナーで、フォームをダブルクリックして、Load イベント ハンドラーを作成します。 Form1.csの先頭に、次の using ステートメントを追加します。

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

既存の Form1 クラスの内容を次のコードに置き換えます。

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

前のコードの Form1_Load メソッドは、WPF コントロールをホストするための一般的な手順を示しています。

  1. 新しい ElementHost オブジェクトを作成します。

  2. コントロールの Dock プロパティを DockStyle.Fillに設定します。

  3. Panel コントロールの Controls コレクションに ElementHost コントロールを追加します。

  4. WPF コントロールのインスタンスを作成します。

  5. フォームで複合コントロールをホストするには、コントロールを ElementHost コントロールの Child プロパティに割り当てます。

Form1_Load メソッドの残りの 2 行は、ハンドラーを 2 つのコントロール イベントにアタッチします。

  • OnButtonClick は、ユーザーが [OK] または [キャンセル] ボタンをクリックしたときに、複合コントロールによってトリガーされるカスタムイベントです。 イベントを処理して、ユーザーの応答を取得し、ユーザーが指定したすべてのデータを収集します。

  • Loaded は、WPF コントロールが完全に読み込まれるときに発生する標準イベントです。 この例では、コントロールのプロパティを使用して複数のグローバル変数を初期化する必要があるため、このイベントがここで使用されます。 フォームの Load イベントの時点では、コントロールは完全には読み込まれず、それらの値は引き続き nullに設定されます。 これらのプロパティにアクセスするには、コントロールの Loaded イベントが発生するまで待つ必要があります。

Loaded イベント ハンドラーは、前のコードに示されています。 OnButtonClick ハンドラーについては、次のセクションで説明します。

OnButtonClick の処理

OnButtonClick イベントは、ユーザーが [OK] ボタン をクリックするか、[キャンセル] ボタン をクリックしたときに発生します。

イベント ハンドラーは、イベント引数の IsOK フィールドをチェックして、どのボタンがクリックされたかを判断します。 lblデータ 変数は、前に説明した Label コントロールに対応します。 ユーザーが [OK] ボタンをクリックすると、コントロールの TextBox コントロールのデータが、対応する Label コントロールに割り当てられます。 ユーザーが [キャンセル]クリックすると、 の値が既定の文字列に設定されます。

次のボタンクリックイベントハンドラコードを 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: ";
    }
}

アプリケーションをビルドして実行します。 WPF 複合コントロールにテキストを追加し、[OK]クリックします。 テキストがラベルに表示されます。 この時点で、ラジオ ボタンを処理するコードは追加されていません。

コントロールの外観の変更

フォームの RadioButton コントロールを使用すると、ユーザーは WPF 複合コントロールの前景色と背景色、およびいくつかのフォント プロパティを変更できます。 背景色は、ElementHost オブジェクトによって公開されます。 残りのプロパティは、コントロールのカスタム プロパティとして公開されます。

フォーム上の各 RadioButton コントロールをダブルクリックして、CheckedChanged イベント ハンドラーを作成します。 CheckedChanged イベント ハンドラーを次のコードに置き換えます。

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

アプリケーションをビルドして実行します。 別のラジオ ボタンをクリックして、WPF 複合コントロールへの影響を確認します。

参考