다음을 통해 공유


연습: WPF에서 Windows Forms 컨트롤 정렬

이 연습은 하이브리드 애플리케이션에서 WPF 레이아웃 기능을 사용하여 Windows Forms 컨트롤을 정렬하는 방법을 보여 줍니다.

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

  • 프로젝트 만들기.
  • 기본 레이아웃 설정 사용
  • 콘텐츠에 맞게 크기 조정
  • 절대 위치 사용
  • 명시적으로 크기 지정
  • 레이아웃 속성 설정
  • z 순서 제한 사항 이해
  • 도킹
  • 표시 유형 설정
  • 늘어나지 않는 컨트롤 호스트
  • 배율 조정
  • 회전
  • 안쪽 여백 및 여백 설정
  • 동적 레이아웃 컨테이너 사용

이 연습에 설명된 작업의 전체 코드 목록은 WPF에서 Windows Forms 컨트롤 정렬 샘플을 참조하세요.

작업을 완료하면 WPF 기반 애플리케이션의 Windows Forms 레이아웃 기능을 이해하게 됩니다.

필수 구성 요소

이 연습을 완료하려면 Visual Studio가 필요합니다.

프로젝트 만들기

프로젝트를 만들고 설정하려면 다음 단계를 수행합니다.

  1. WpfLayoutHostingWf라는 WPF 애플리케이션 프로젝트를 만듭니다.

  2. 솔루션 탐색기에서 다음 어셈블리에 대한 참조를 추가합니다.

    • WindowsFormsIntegration
    • System.Windows.Forms
    • System.Drawing
  3. MainWindow.xaml을 두 번 클릭하여 XAML 보기에서 엽니다.

  4. Window 요소에서 다음 Windows Forms 네임스페이스 매핑을 추가합니다.

    xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
    
  5. Grid 요소에서 ShowGridLines 속성을 true로 설정하고 5개의 행과 3개의 열을 정의합니다.

    <Grid ShowGridLines="true">
      <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
      </Grid.RowDefinitions>
    
      <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
        <ColumnDefinition/>
      </Grid.ColumnDefinitions>
    

기본 레이아웃 설정 사용

기본적으로 WindowsFormsHost 요소는 호스트된 Windows Forms 컨트롤의 레이아웃을 처리합니다.

기본 레이아웃 설정을 사용하려면 다음 단계를 수행합니다.

  1. 다음 XAML을 Grid 요소에 복사합니다.

    <!-- Default layout. -->
    <Canvas Grid.Row="0" Grid.Column="0">
      <WindowsFormsHost Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Canvas>
    
  2. F5 키를 눌러 애플리케이션을 빌드하고 실행합니다. Windows Forms System.Windows.Forms.Button 컨트롤이 Canvas에 나타납니다. 호스트된 컨트롤은 해당 콘텐츠에 따라 크기가 조정되고 WindowsFormsHost 요소는 호스트된 컨트롤에 맞게 크기가 조정됩니다.

콘텐츠에 맞게 크기 조정

WindowsFormsHost 요소는 호스트된 컨트롤이 콘텐츠를 제대로 표시할 수 있는 크기로 조정되도록 합니다.

콘텐츠 크기를 조정하려면 다음 단계를 수행합니다.

  1. 다음 XAML을 Grid 요소에 복사합니다.

    <!-- Sizing to content. -->
    <Canvas Grid.Row="1" Grid.Column="0">
      <WindowsFormsHost Background="Orange">
        <wf:Button Text="Windows Forms control with more content" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Canvas>
    
    <Canvas Grid.Row="2" Grid.Column="0">
      <WindowsFormsHost FontSize="24" Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Canvas>
    
  2. F5 키를 눌러 애플리케이션을 빌드하고 실행합니다. 더 긴 텍스트 문자열과 더 큰 글꼴 크기를 제대로 표시하도록 두 개의 새 단추 컨트롤 크기가 조정되며 호스트된 컨트롤에 맞게 WindowsFormsHost 요소의 크기가 조정됩니다.

절대 위치 사용

절대 위치 지정을 사용하여 WindowsFormsHost 요소를 사용자 인터페이스(UI) 어디에나 배치할 수 있습니다.

절대 위치 지정을 사용하려면 다음 단계를 수행합니다.

  1. 다음 XAML을 Grid 요소에 복사합니다.

    <!-- Absolute positioning. -->
    <Canvas Grid.Row="3" Grid.Column="0">
      <WindowsFormsHost Canvas.Top="20" Canvas.Left="20" Background="Yellow">
        <wf:Button Text="Windows Forms control with absolute positioning" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Canvas>
    
  2. F5 키를 눌러 애플리케이션을 빌드하고 실행합니다. WindowsFormsHost 요소가 표 셀의 위쪽에서 20픽셀 및 왼쪽에서 20픽셀 위치에 배치됩니다.

명시적으로 크기 지정

WidthHeight 속성을 사용하여 WindowsFormsHost 요소의 크기를 지정할 수 있습니다.

크기를 명시적으로 지정하려면 다음 단계를 수행합니다.

  1. 다음 XAML을 Grid 요소에 복사합니다.

    <!-- Explicit sizing. -->
    <Canvas Grid.Row="4" Grid.Column="0">
      <WindowsFormsHost Width="50" Height="70" Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Canvas>
    
  2. F5 키를 눌러 애플리케이션을 빌드하고 실행합니다. WindowsFormsHost 요소가 너비 50픽셀 x 높이 70픽셀 크기로 설정되어 기본 레이아웃 설정보다 작습니다. Windows Forms 컨트롤의 콘텐츠는 그에 따라 다시 정렬됩니다.

레이아웃 속성 설정

항상 호스트된 컨트롤에서 WindowsFormsHost 요소의 속성을 사용하여 레이아웃 관련 속성을 설정합니다. 호스트된 컨트롤에서 직접 레이아웃 속성을 설정하면 의도하지 않은 결과가 생성됩니다.

XAML의 호스트된 컨트롤에서 레이아웃 관련 속성을 설정하면 아무 효과가 없습니다.

호스트된 컨트롤에서 속성 설정의 결과를 확인하려면 다음 단계를 수행합니다.

  1. 다음 XAML을 Grid 요소에 복사합니다.

    <!-- Setting hosted control properties directly. -->
    <Canvas Grid.Row="0" Grid.Column="1">
      <WindowsFormsHost Width="160" Height="50" Background="Yellow">
        <wf:Button Name="button1" Click="button1_Click" Text="Click me" FlatStyle="Flat" BackColor="Green"/>
      </WindowsFormsHost>
    </Canvas>
    
  2. 솔루션 탐색기에서 MainWindow.xaml.vb 또는 MainWindow.xaml.cs를 두 번 클릭하여 코드 편집기에서 엽니다.

  3. 다음 코드를 MainWindow 클래스 정의에 복사합니다.

    private void button1_Click(object sender, EventArgs e )
    {
        System.Windows.Forms.Button b = sender as System.Windows.Forms.Button;
    
        b.Top = 20;
        b.Left = 20;
    }
    
    Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs)
        Dim b As System.Windows.Forms.Button = sender
    
        b.Top = 20
        b.Left = 20
    
    End Sub
    
  4. F5 키를 눌러 애플리케이션을 빌드하고 실행합니다.

  5. Click me 단추를 클릭합니다. button1_Click 이벤트 처리기는 호스트된 컨트롤에서 TopLeft 속성을 설정합니다. 이로 인해 WindowsFormsHost 요소 안에서 호스트된 컨트롤의 위치가 변경됩니다. 호스트는 동일한 화면 영역을 유지하지만 호스트된 컨트롤은 잘립니다. 대신 호스트된 컨트롤은 항상 WindowsFormsHost 요소를 채워야 합니다.

Z 순서 제한 사항 이해

보이는 WindowsFormsHost 요소는 항상 다른 WPF 요소 위에 그려지며, Z 순서의 영향을 받지 않습니다. 이 Z 순서 동작을 확인하려면 다음을 수행합니다.

  1. 다음 XAML을 Grid 요소에 복사합니다.

    <!-- Z-order demonstration. -->
    <Canvas Grid.Row="1" Grid.Column="1">
      <WindowsFormsHost Canvas.Top="20" Canvas.Left="20" Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
      <Label Content="A WPF label" FontSize="24"/>
    </Canvas>
    
  2. F5 키를 눌러 애플리케이션을 빌드하고 실행합니다. WindowsFormsHost 요소는 레이블 요소 위에 그려집니다.

도킹

WindowsFormsHost 요소는 WPF 도킹을 지원합니다. Dock 연결된 속성을 설정하여 DockPanel 요소에 호스트된 컨트롤을 도킹합니다.

호스트된 컨트롤을 도킹하려면 다음 단계를 수행합니다.

  1. 다음 XAML을 Grid 요소에 복사합니다.

    <!-- Docking a WindowsFormsHost element. -->
    <DockPanel LastChildFill="false"  Grid.Row="2" Grid.Column="1">
      <WindowsFormsHost DockPanel.Dock="Right"  Canvas.Top="20" Canvas.Left="20" Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </DockPanel>
    
  2. F5 키를 눌러 애플리케이션을 빌드하고 실행합니다. WindowsFormsHost 요소는 DockPanel 요소의 오른쪽에 도킹됩니다.

표시 유형 설정

WindowsFormsHost 요소에서 Visibility 설정하여 Windows Forms 컨트롤을 보이지 않게 만들거나 축소할 수 있습니다. 컨트롤이 보이지 않으면 표시되지는 않지만 레이아웃 공간은 사용합니다. 컨트롤이 축소되면 표시되지 않고 레이아웃 공간도 자치하지 않습니다.

호스트된 컨트롤의 표시 유형을 설정하려면 다음 단계를 수행합니다.

  1. 다음 XAML을 Grid 요소에 복사합니다.

    <!-- Setting Visibility to hidden and collapsed. -->
    <StackPanel Grid.Row="3" Grid.Column="1">
      <Button Name="button2" Click="button2_Click" Content="Click to make invisible" Background="OrangeRed"/>
      <WindowsFormsHost Name="host1"  Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
      <Button Name="button3" Click="button3_Click" Content="Click to collapse" Background="OrangeRed"/>
    </StackPanel>
    
  2. MainWindow.xaml.vb 또는 MainWindow.xaml.cs에서 다음 코드를 클래스 정의에 복사합니다.

    private void button2_Click(object sender, EventArgs e)
    {
        this.host1.Visibility = Visibility.Hidden;
    }
    
    private void button3_Click(object sender, EventArgs e)
    {
        this.host1.Visibility = Visibility.Collapsed;
    }
    
    Private Sub button2_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Me.host1.Visibility = Windows.Visibility.Hidden
    End Sub
    
    
    Private Sub button3_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Me.host1.Visibility = Windows.Visibility.Collapsed
    End Sub
    
  3. F5 키를 눌러 애플리케이션을 빌드하고 실행합니다.

  4. 보이지 않게 만들려면 클릭 단추를 클릭하여 WindowsFormsHost 요소를 보이지 않게 만듭니다.

  5. 축소하려면 클릭 단추를 클릭하여 레이아웃에서 WindowsFormsHost 요소를 완전히 숨깁니다. Windows Forms 컨트롤이 축소되면 주변 요소가 다시 정렬되어 해당 공간을 사용합니다.

늘어나지 않는 컨트롤 호스트

일부 Windows Forms 컨트롤은 고정 크기이며 레이아웃에서 사용 가능한 공간을 채우도록 늘어나지 않습니다. 예를 들어 MonthCalendar 컨트롤은 고정된 간격으로 달을 표시합니다.

늘어나지 않는 컨트롤을 호스트하려면 다음 단계를 수행합니다.

  1. 다음 XAML을 Grid 요소에 복사합니다.

    <!-- Hosting a control that does not stretch. -->
    <!-- The MonthCalendar has a discrete size. -->
    <StackPanel Grid.Row="4" Grid.Column="1">
      <Label Content="A WPF element" Background="OrangeRed"/>
      <WindowsFormsHost Background="Yellow">
        <wf:MonthCalendar/>
      </WindowsFormsHost>
      <Label Content="Another WPF element" Background="OrangeRed"/>
    </StackPanel>
    
  2. F5 키를 눌러 애플리케이션을 빌드하고 실행합니다. WindowsFormsHost element 요소는 그리드 행의 중심에 위치하지만 사용 가능한 공간을 채우도록 늘어나지 않습니다. 창이 충분히 큰 경우 둘 이상의 달이 호스트된 MonthCalendar 컨트롤에 의해 표시되는 것을 확인할 수 있지만 이러한 달은 행에서 가운데 맞춤됩니다. WPF 레이아웃 엔진은 사용 가능한 공간을 채우도록 크기를 조정할 수 없는 요소를 가운데 맞춤합니다.

크기 조정

WPF 요소와 달리 대부분의 Windows Forms 컨트롤은 지속적으로 확장 가능하지 않습니다. 사용자 지정 크기 조정을 제공하려면 WindowsFormsHost.ScaleChild 메서드를 재정의합니다.

기본 동작을 사용하여 호스트된 컨트롤 크기를 조정하려면 다음 단계를 수행합니다.

  1. 다음 XAML을 Grid 요소에 복사합니다.

    <!-- Scaling transformation. -->
    <StackPanel Grid.Row="0" Grid.Column="2">
      
      <StackPanel.RenderTransform>
        <ScaleTransform CenterX="0" CenterY="0" ScaleX="0.5" ScaleY="0.5" />
      </StackPanel.RenderTransform>
    
      <Label Content="A WPF UIElement" Background="OrangeRed"/>
      
      <WindowsFormsHost Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
      
      <Label Content="Another WPF UIElement" Background="OrangeRed"/>
      
    </StackPanel>
    
  2. F5 키를 눌러 애플리케이션을 빌드하고 실행합니다. 호스트된 컨트롤과 해당 주변 요소가 0.5의 비율로 배율 조정됩니다. 그러나 호스트된 컨트롤의 글꼴은 배율 조정되지 않습니다.

회전

WPF 요소와 달리 Windows Forms 컨트롤은 회전을 지원하지 않습니다. WindowsFormsHost 요소는 회전 변환이 적용될 때 다른 WPF 요소와 함께 회전하지 않습니다. 180도가 아닌 회전 값은 LayoutError 이벤트를 발생시킵니다.

하이브리드 애플리케이션에서 회전의 효과를 확인하려면 다음 단계를 수행합니다.

  1. 다음 XAML을 Grid 요소에 복사합니다.

    <!-- Rotation transformation. -->
    <StackPanel Grid.Row="1" Grid.Column="2">
    
      <StackPanel.RenderTransform>
        <RotateTransform CenterX="200" CenterY="50" Angle="180" />
      </StackPanel.RenderTransform>
    
      <Label Content="A WPF element" Background="OrangeRed"/>
    
      <WindowsFormsHost Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
    
      <Label Content="Another WPF element" Background="OrangeRed"/>
    
    </StackPanel>
    
  2. F5 키를 눌러 애플리케이션을 빌드하고 실행합니다. 호스트된 컨트롤은 회전되지 않지만 주변 요소는 180도 각도로 회전됩니다. 요소를 표시하려면 창의 크기를 조정해야 할 수 있습니다.

안쪽 여백 및 여백 설정

WPF 레이아웃의 안쪽 여백 및 여백은 Windows Forms의 안쪽 여백 및 여백과 비슷합니다. WindowsFormsHost 요소에서 PaddingMargin 속성을 설정하기만 하면 됩니다.

호스트된 컨트롤의 안쪽 여백 및 여백을 설정하려면 다음 단계를 수행합니다.

  1. 다음 XAML을 Grid 요소에 복사합니다.

    <!-- Padding. -->
    <Canvas Grid.Row="2" Grid.Column="2">
      <WindowsFormsHost Padding="0, 20, 0, 0" Background="Yellow">
        <wf:Button Text="Windows Forms control with padding" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Canvas>
    
    <!-- Margin. -->
    <Canvas Grid.Row="3" Grid.Column="2">
      <WindowsFormsHost Margin="20, 20, 0, 0" Background="Yellow">
        <wf:Button Text="Windows Forms control with margin" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Canvas>
    
  2. F5 키를 눌러 애플리케이션을 빌드하고 실행합니다. 안쪽 여백 및 여백 설정이 Windows Forms에서 적용된 것과 같은 방식으로 호스트된 Windows Forms 컨트롤에 적용됩니다.

동적 레이아웃 컨테이너 사용

Windows Forms는 FlowLayoutPanelTableLayoutPanel이라는 두 개의 동적 레이아웃 컨테이너를 제공합니다. 이러한 컨테이너는 WPF 레이아웃에서도 사용할 수 있습니다.

동적 레이아웃 컨테이너를 사용하려면 다음 단계를 수행합니다.

  1. 다음 XAML을 Grid 요소에 복사합니다.

    <!-- Flow layout. -->
    <DockPanel Grid.Row="4" Grid.Column="2">
      <WindowsFormsHost Name="flowLayoutHost" Background="Yellow">
        <wf:FlowLayoutPanel/>
      </WindowsFormsHost>
    </DockPanel>
    
  2. MainWindow.xaml.vb 또는 MainWindow.xaml.cs에서 다음 코드를 클래스 정의에 복사합니다.

    private void InitializeFlowLayoutPanel()
    {
        System.Windows.Forms.FlowLayoutPanel flp =
            this.flowLayoutHost.Child as System.Windows.Forms.FlowLayoutPanel;
    
        flp.WrapContents = true;
    
        const int numButtons = 6;
    
        for (int i = 0; i < numButtons; i++)
        {
            System.Windows.Forms.Button b = new System.Windows.Forms.Button();
            b.Text = "Button";
            b.BackColor = System.Drawing.Color.AliceBlue;
            b.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
    
            flp.Controls.Add(b);
        }
    }
    
    Private Sub InitializeFlowLayoutPanel()
        Dim flp As System.Windows.Forms.FlowLayoutPanel = Me.flowLayoutHost.Child
    
        flp.WrapContents = True
    
        Const numButtons As Integer = 6
    
        Dim i As Integer
        For i = 0 To numButtons
            Dim b As New System.Windows.Forms.Button()
            b.Text = "Button"
            b.BackColor = System.Drawing.Color.AliceBlue
            b.FlatStyle = System.Windows.Forms.FlatStyle.Flat
    
            flp.Controls.Add(b)
        Next i
    
    End Sub
    
  3. 생성자에서 InitializeFlowLayoutPanel 메서드 호출을 추가합니다.

    public MainWindow()
    {
        InitializeComponent();
    
        this.InitializeFlowLayoutPanel();
    }
    
    Public Sub New()
        InitializeComponent()
    
        Me.InitializeFlowLayoutPanel()
    
    End Sub
    
  4. F5 키를 눌러 애플리케이션을 빌드하고 실행합니다. WindowsFormsHost 요소는 DockPanel을 채우고, FlowLayoutPanel은 자식 컨트롤을 기본 FlowDirection으로 정렬합니다.

참고 항목