チュートリアル: WPF での Windows フォーム コントロールの配置

このチュートリアルでは、WPF レイアウト機能を使用して、ハイブリッド アプリケーションで Windows フォーム コントロールを配置する方法について説明します。

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

  • プロジェクトの作成。
  • 既定のレイアウト設定の使用。
  • コンテンツに合わせたサイズの変更。
  • 絶対配置の使用。
  • サイズの明示的な指定。
  • レイアウト プロパティの設定。
  • z オーダーの制限の理解。
  • ドッキング。
  • 可視性の設定。
  • 伸縮しないコントロールのホスト。
  • スケーリング。
  • 回転。
  • パディングとマージンの設定。
  • 動的レイアウト コンテナーの使用。

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

完了すると、WPF ベースのアプリケーションでの Windows フォーム レイアウトの機能について理解できます。

必須コンポーネント

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

プロジェクトの作成

プロジェクトを作成して設定するには、次の手順を実行します。

  1. WpfLayoutHostingWf という名前の WPF アプリケーション プロジェクトを作成します。

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

    • WindowsFormsIntegration
    • System.Windows.Forms
    • System.Drawing
  3. MainWindow.xaml をダブルクリックして、XAML ビューで開きます。

  4. Window 要素に、次の Windows フォーム名前空間マッピングを追加します。

    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 フォーム コントロールのレイアウトが処理されます。

既定のレイアウト設定を使用するには、次の手順を実行します。

  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 フォーム 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 キーを押してアプリケーションをビルドし、実行します。 2 つの新しいボタン コントロールは、長いテキスト文字列と大きなフォント サイズが適切に表示されるようにサイズが変更され、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 ピクセルの位置に配置されます。

サイズの明示的な指定

Width および Height プロパティを使用して、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 ピクセル、高さ 70 ピクセルのサイズに設定されています。これは既定のレイアウト設定よりも小さいサイズです。 Windows フォーム コントロールのコンテンツは、それに応じて再配置されます。

レイアウト プロパティの設定

ホストされているコントロールには、常に、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 イベント ハンドラーによって、ホストされているコントロールに Top および Left プロパティが設定されます。 これにより、ホストされているコントロールが 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 要素は label 要素の上に描画されます。

ドッキング

WindowsFormsHost 要素は WPF のドッキングをサポートします。 ホストされているコントロールを DockPanel 要素にドッキングするように Dock 添付プロパティを設定します。

ホストされているコントロールをドッキングするには、次の手順を実行します。

  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 フォーム コントロールを非表示にしたり折りたたんだりすることができます。 コントロールを非表示にすると、そのコントロールは表示されませんが、レイアウト空間は使用されます。 コントロールを折りたたむと、そのコントロールは表示されず、レイアウト空間も使用されません。

ホストされているコントロールの可視性を設定するには、次の手順を実行します。

  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. [Click to make invisible](クリックして非表示にする) ボタンをクリックして WindowsFormsHost 要素を非表示にします。

  5. [Click to collapse](クリックして折りたたむ) ボタンをクリックして、レイアウトから WindowsFormsHost 要素を完全に非表示にします。 Windows フォーム コントロールが折りたたまれ、周りの要素が再配置されて、そのスペースが使用されます。

伸縮しないコントロールのホスト

一部の Windows フォーム コントロールは、サイズが固定され、レイアウト内の使用可能なスペースに合わせて伸縮しません。 たとえば、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 要素はグリッド行で中央揃えになりますが、使用可能なスペースに合わせて伸縮されることはありません。 ウィンドウが十分に大きい場合は、ホストされている MonthCalendar コントロールによって 2 か月以上の月が表示される場合もありますが、これらは行内で中央揃えになります。 WPF レイアウト エンジンによって、使用可能なスペースに合わせてサイズを変更できない要素が中央揃えにされます。

スケーリング

WPF 要素と異なり、ほとんどの Windows フォーム コントロールは継続的にスケーリングすることはできません。 カスタムのスケーリングを提供するには、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 フォーム コントロールは回転をサポートしません。 回転変換が適用されても、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 フォーム のパディングとマージンと同様です。 WindowsFormsHost 要素に Padding および Margin プロパティを設定するだけです。

ホストされているコントロールのパディングとマージンを設定するには、次の手順を実行します。

  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 フォーム で適用される場合と同じように、ホストされている Windows フォーム コントロールに適用されます。

動的レイアウト コンテナーの使用

Windows フォームには、FlowLayoutPanelTableLayoutPanel という 2 つの動的レイアウト コンテナーが用意されています。 これらのコンテナーは、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 にその子コントロールが配置されます。

関連項目