Share via


연습: ElementHost 컨트롤을 사용하여 속성 매핑

이 연습에서는 PropertyMap 속성을 사용하여 Windows Forms 속성을 호스팅된 WPF 요소의 해당 속성에 매핑하는 방법을 보여 줍니다.

이 연습에서 설명하는 작업은 다음과 같습니다.

  • 프로젝트 만들기.

  • 새 속성 매핑 정의.

  • 기본 속성 매핑 제거.

  • 기본 속성 매핑 확장.

완료하면 Windows Forms 속성을 호스팅된 요소의 해당 WPF 속성에 매핑할 수 있습니다.

필수 구성 요소

이 연습을 완료하려면 다음과 같은 구성 요소가 필요합니다.

  • Visual Studio 2017

프로젝트 만들기

프로젝트를 만들려면

  1. PropertyMappingWithElementHost라는 Windows Forms 앱 프로젝트를 만듭니다.

  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 Forms 디자이너에서 Form1을 엽니다. 양식을 두 번 클릭하여 Load 이벤트용 이벤트 처리기를 추가합니다.

  5. Windows Forms 디자이너로 돌아가 양식의 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를 눌러 애플리케이션을 빌드 및 실행합니다.

참고 항목