Share via


チュートリアル: ElementHost コントロールを使用したプロパティの割り当て

このチュートリアルでは、PropertyMap プロパティを使用して、ホストされている WPF 要素の対応するプロパティに Windows フォーム プロパティをマップする方法を示します。

このチュートリアルでは、以下のタスクを行います。

  • プロジェクトの作成。

  • 新しいプロパティ マッピングの定義。

  • 既定のプロパティ マッピングの削除。

  • 既定のプロパティ マッピングの拡張。

完了すると、ホストされている要素の対応する WPF プロパティに Windows フォーム プロパティをマップできるようになります。

必須コンポーネント

このチュートリアルを実行するには、次のコンポーネントが必要です。

  • Visual Studio 2017

プロジェクトの作成

プロジェクトを作成するには

  1. PropertyMappingWithElementHost という名前の Windows フォーム アプリ プロジェクトを作成します。

  2. ソリューション エクスプローラーで、次の WPF アセンブリへの参照を追加します。

    • PresentationCore

    • PresentationFramework

    • WindowsBase

    • WindowsFormsIntegration

  3. Form1 コード ファイルの先頭に次のコードをコピーします。

    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Forms.Integration;
    
    Imports System.Windows
    Imports System.Windows.Media
    Imports System.Windows.Media.Imaging
    Imports System.Windows.Forms.Integration
    
  4. Windows フォーム デザイナーで Form1 を開きます。 フォームをダブルクリックして、Load イベントのイベント ハンドラーを追加します。

  5. Windows フォーム デザイナーに戻り、フォームの Resize イベントのイベント ハンドラーを追加します。 詳細については、方法: デザイナーを使用してイベント ハンドラーを作成する」を参照してください。

  6. Form1 クラスで ElementHost フィールドを宣言します。

    ElementHost elemHost = null;
    
    Private elemHost As ElementHost = Nothing
    

新しいプロパティ マッピングの定義

ElementHost コントロールには、いくつかの既定のプロパティ マッピングが用意されています。 ElementHost コントロールの PropertyMap に対して Add メソッドを呼び出して、新しいプロパティ マッピングを追加します。

新しいプロパティ マッピングを定義するには

  1. 次のコードを Form1 クラスの定義にコピーします。

    // The AddMarginMapping method adds a new property mapping
    // for the Margin property.
    private void AddMarginMapping()
    {
        elemHost.PropertyMap.Add(
            "Margin",
            new PropertyTranslator(OnMarginChange));
    }
    
    // The OnMarginChange method implements the mapping
    // from the Windows Forms Margin property to the
    // Windows Presentation Foundation Margin property.
    //
    // The provided Padding value is used to construct
    // a Thickness value for the hosted element's Margin
    // property.
    private void OnMarginChange(object h, String propertyName, object value)
    {
        ElementHost host = h as ElementHost;
        Padding p = (Padding)value;
        System.Windows.Controls.Button wpfButton =
            host.Child as System.Windows.Controls.Button;
    
        Thickness t = new Thickness(p.Left, p.Top, p.Right, p.Bottom );
    
        wpfButton.Margin = t;
    }
    
    ' The AddMarginMapping method adds a new property mapping
    ' for the Margin property.
    Private Sub AddMarginMapping()
    
        elemHost.PropertyMap.Add( _
            "Margin", _
            New PropertyTranslator(AddressOf OnMarginChange))
    
    End Sub
    
    
    ' The OnMarginChange method implements the mapping 
    ' from the Windows Forms Margin property to the
    ' Windows Presentation Foundation Margin property.
    '
    ' The provided Padding value is used to construct 
    ' a Thickness value for the hosted element's Margin
    ' property.
    Private Sub OnMarginChange( _
    ByVal h As Object, _
    ByVal propertyName As String, _
    ByVal value As Object)
    
        Dim host As ElementHost = h
        Dim p As Padding = CType(value, Padding)
        Dim wpfButton As System.Windows.Controls.Button = host.Child
    
    
        Dim t As New Thickness(p.Left, p.Top, p.Right, p.Bottom)
    
        wpfButton.Margin = t
    
    End Sub
    

    AddMarginMapping メソッドを使用して、Margin プロパティの新しいマッピングを追加します。

    OnMarginChange メソッドを使用して、Margin プロパティを WPF Margin プロパティに変換します。

  2. 次のコードを Form1 クラスの定義にコピーします。

    // The AddRegionMapping method assigns a custom
    // mapping for the Region property.
    private void AddRegionMapping()
    {
        elemHost.PropertyMap.Add(
            "Region",
            new PropertyTranslator(OnRegionChange));
    }
    
    // The OnRegionChange method assigns an EllipseGeometry to
    // the hosted element's Clip property.
    private void OnRegionChange(
        object h,
        String propertyName,
        object value)
    {
        ElementHost host = h as ElementHost;
        System.Windows.Controls.Button wpfButton =
            host.Child as System.Windows.Controls.Button;
    
        wpfButton.Clip = new EllipseGeometry(new Rect(
            0,
            0,
            wpfButton.ActualWidth,
            wpfButton.ActualHeight));
    }
    
    // The Form1_Resize method handles the form's Resize event.
    // It calls the OnRegionChange method explicitly to
    // assign a new clipping geometry to the hosted element.
    private void Form1_Resize(object sender, EventArgs e)
    {
        this.OnRegionChange(elemHost, "Region", null);
    }
    
    ' The AddRegionMapping method assigns a custom 
    ' mapping for the Region property.
    Private Sub AddRegionMapping()
    
        elemHost.PropertyMap.Add( _
            "Region", _
            New PropertyTranslator(AddressOf OnRegionChange))
    
    End Sub
    
    
    ' The OnRegionChange method assigns an EllipseGeometry to
    ' the hosted element's Clip property.
    Private Sub OnRegionChange( _
    ByVal h As Object, _
    ByVal propertyName As String, _
    ByVal value As Object)
    
        Dim host As ElementHost = h
    
        Dim wpfButton As System.Windows.Controls.Button = host.Child
    
        wpfButton.Clip = New EllipseGeometry(New Rect( _
            0, _
            0, _
            wpfButton.ActualWidth, _
            wpfButton.ActualHeight))
    
    End Sub
    
    
    ' The Form1_Resize method handles the form's Resize event.
    ' It calls the OnRegionChange method explicitly to 
    ' assign a new clipping geometry to the hosted element.
    Private Sub Form1_Resize( _
    ByVal sender As Object, _
    ByVal e As EventArgs) Handles MyBase.Resize
    
        If elemHost IsNot Nothing Then
            Me.OnRegionChange(elemHost, "Region", Nothing)
        End If
    
    End Sub
    

    AddRegionMapping メソッドを使用して、Region プロパティの新しいマッピングを追加します。

    OnRegionChange メソッドを使用して、Region プロパティを WPF Clip プロパティに変換します。

    Form1_Resize メソッドを使用して、フォームの Resize イベントを処理し、ホストされている要素に合わせてクリッピング領域のサイズを変更します。

既定のプロパティ マッピングの削除

ElementHost コントロールの PropertyMap に対して Remove メソッドを呼び出して、既定のプロパティ マッピングを削除します。

既定のプロパティ マッピングを削除するには

  • 次のコードを Form1 クラスの定義にコピーします。

    // The RemoveCursorMapping method deletes the default
    // mapping for the Cursor property.
    private void RemoveCursorMapping()
    {
        elemHost.PropertyMap.Remove("Cursor");
    }
    
    ' The RemoveCursorMapping method deletes the default
    ' mapping for the Cursor property.
    Private Sub RemoveCursorMapping()
        elemHost.PropertyMap.Remove("Cursor")
    End Sub
    

    RemoveCursorMapping メソッドを使用して、Cursor プロパティの既定のマッピングを削除します。

既定のプロパティ マッピングの拡張

既定のプロパティ マッピングを使用できます。また、独自のマッピングを使用して拡張することもできます。

既定のプロパティ マッピングを拡張するには

  • 次のコードを Form1 クラスの定義にコピーします。

    // The ExtendBackColorMapping method adds a property
    // translator if a mapping already exists.
    private void ExtendBackColorMapping()
    {
        if (elemHost.PropertyMap["BackColor"] != null)
        {
            elemHost.PropertyMap["BackColor"] +=
                new PropertyTranslator(OnBackColorChange);
        }
    }
    
    // The OnBackColorChange method assigns a specific image
    // to the hosted element's Background property.
    private void OnBackColorChange(object h, String propertyName, object value)
    {
        ElementHost host = h as ElementHost;
        System.Windows.Controls.Button wpfButton =
            host.Child as System.Windows.Controls.Button;
    
        ImageBrush b = new ImageBrush(new BitmapImage(
            new Uri(@"file:///C:\WINDOWS\Santa Fe Stucco.bmp")));
        wpfButton.Background = b;
    }
    
    ' The ExtendBackColorMapping method adds a property
    ' translator if a mapping already exists.
    Private Sub ExtendBackColorMapping()
    
        If elemHost.PropertyMap("BackColor") IsNot Nothing Then
    
            elemHost.PropertyMap("BackColor") = PropertyTranslator.Combine( _
                elemHost.PropertyMap("BackColor"), _
                PropertyTranslator.CreateDelegate( _
                GetType(PropertyTranslator), _
                Me, _
                "OnBackColorChange"))
        End If
    
    End Sub
    
    
    ' The OnBackColorChange method assigns a specific image 
    ' to the hosted element's Background property.
    Private Sub OnBackColorChange( _
    ByVal h As Object, _
    ByVal propertyName As String, _
    ByVal value As Object)
    
        Dim host As ElementHost = h
        Dim wpfButton As System.Windows.Controls.Button = host.Child
        Dim b As New ImageBrush(New BitmapImage( _
            New Uri("file:///C:\WINDOWS\Santa Fe Stucco.bmp")))
        wpfButton.Background = b
    
    End Sub
    

    ExtendBackColorMapping メソッドを使用して、カスタム プロパティ トランスレーターを既存の BackColor プロパティ マッピングに追加します。

    OnBackColorChange メソッドを使用して、ホストされているコントロールの Background プロパティに特定の画像を割り当てます。 OnBackColorChange メソッドは、既定のプロパティ マッピングが適用された後に呼び出されます。

プロパティ マッピングを初期化する

  1. 次のコードを Form1 クラスの定義にコピーします。

    private void Form1_Load(object sender, EventArgs e)
    {
        // Create the ElementHost control.
        elemHost = new ElementHost();
        elemHost.Dock = DockStyle.Fill;
        this.Controls.Add(elemHost);
    
        // Create a Windows Presentation Foundation Button element
        // and assign it as the ElementHost control's child.
        System.Windows.Controls.Button wpfButton = new System.Windows.Controls.Button();
        wpfButton.Content = "Windows Presentation Foundation Button";
        elemHost.Child = wpfButton;
    
        // Map the Margin property.
        this.AddMarginMapping();
    
        // Remove the mapping for the Cursor property.
        this.RemoveCursorMapping();
    
        // Add a mapping for the Region property.
        this.AddRegionMapping();
    
        // Add another mapping for the BackColor property.
        this.ExtendBackColorMapping();
    
        // Cause the OnMarginChange delegate to be called.
        elemHost.Margin = new Padding(23, 23, 23, 23);
    
        // Cause the OnRegionChange delegate to be called.
        elemHost.Region = new Region();
    
        // Cause the OnBackColorChange delegate to be called.
        elemHost.BackColor = System.Drawing.Color.AliceBlue;
    }
    
    Private Sub Form1_Load( _
    ByVal sender As Object, _
    ByVal e As EventArgs) Handles MyBase.Load
    
        ' Create the ElementHost control.
        elemHost = New ElementHost()
        elemHost.Dock = DockStyle.Fill
        Me.Controls.Add(elemHost)
    
        ' Create a Windows Presentation Foundation Button element 
        ' and assign it as the ElementHost control's child. 
        Dim wpfButton As New System.Windows.Controls.Button()
        wpfButton.Content = "Windows Presentation Foundation Button"
        elemHost.Child = wpfButton
    
        ' Map the Margin property.
        Me.AddMarginMapping()
    
        ' Remove the mapping for the Cursor property.
        Me.RemoveCursorMapping()
    
        ' Add a mapping for the Region property.
        Me.AddRegionMapping()
    
        ' Add another mapping for the BackColor property.
        Me.ExtendBackColorMapping()
    
        ' Cause the OnMarginChange delegate to be called.
        elemHost.Margin = New Padding(23, 23, 23, 23)
    
        ' Cause the OnRegionChange delegate to be called.
        elemHost.Region = New [Region]()
    
        ' Cause the OnBackColorChange delegate to be called.
        elemHost.BackColor = System.Drawing.Color.AliceBlue
    
    End Sub
    

    Form1_Load メソッドを使用して Load イベントを処理し、次の初期化を実行します。

    • WPF Button 要素を作成します。

    • このチュートリアルで前に定義したメソッドを呼び出して、プロパティ マッピングを設定します。

    • マップされたプロパティに初期値を割り当てます。

  2. F5 キーを押してアプリケーションをビルドし、実行します。

関連項目