WindowsFormsHostを使用したときの描画問題

 WPF4でWindowsFormsHostを使用した場合、下記のページに書かれているようないくつかの問題がありました。

ハイブリッド アプリケーションのトラブルシューティング | Microsoft Docs



 その中でも「WPFでホストされているWindowsフォームコントロールは、常にWPFコンテンツの一番上に表示されます。」という問題は影響度の大きい問題であり、WindowsFormsHostを使った相互運用を困難なものとしている原因の1つでした。この問題がWPF4.5のDeveloper Previewで改善されています。

What's New in WPF Version 4.5 | Microsoft Docs



 WPF4.5での改善を確認する前に、まずはWPF4でどのような状態だったのかを見ておきたいと思います。


XAML


<Window x:Class="WindowsFormsHostAirspaceIssue.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:forms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
Title="MainWindow" Height="350" Width="525" FontSize="24pt">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<Border Background="LightBlue"/>
<Border BorderBrush="Black" BorderThickness="3" Grid.Column="1">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<UniformGrid Rows="2">
<WindowsFormsHost>
<forms:Label Text="Windowsフォーム" BackColor="LightGreen" TextAlign="TopRight"/>
</WindowsFormsHost>
<TextBlock Text="WPF" Background="LightBlue" TextAlignment="Right"/>
</UniformGrid>
</ScrollViewer>
</Border>
<Border Grid.Column="2" Background="LightBlue"/>
</Grid>
<StackPanel Orientation="Horizontal" Grid.Row="1" VerticalAlignment="Center">
<Rectangle Fill="LightGreen" Width="50" Height="50" Margin="10"/>
<TextBlock Text="Windowsフォームの領域" FontSize="12pt" VerticalAlignment="Center" Margin="10"/>
<Rectangle Fill="LightBlue" Width="50" Height="50" Margin="10"/>
<TextBlock Text="WPFの領域" FontSize="12pt" VerticalAlignment="Center" Margin="10"/>
</StackPanel>
</Grid>
</Window>





 ウィンドウの横幅を少し小さくすすると下の図のようになります。








 WindowsFormsHostが常にWPFコンテンツの一番上に表示されることを確認できたかと思います。


 次にWPF4.5でどのように改善されているのかを確認したいと思います。このプロジェクトをWPF4.5で実行するだけで改善されるわけではありません。いくつかプロパティを設定する必要があります。これは互換性の問題からデフォルトの動作を変えるわけにはいかなったためと思われます。


 具体的にはIsRedirectedプロパティCompositionModeプロパティの2つです。


XAML

<WindowsFormsHost IsRedirected="True" CompositionMode="OutputOnly">
<forms:Label Text="Windowsフォーム" BackColor="LightGreen" TextAlign="TopRight"/>
</WindowsFormsHost>


 IsRedirectedプロパティをTrue、CompositionModeプロパティをNone以外に設定することでWindowsFormsHostの描画内容がVisualBrushとしてWPFコンテンツ上に描画されるようになります。CompositionModeプロパティがOutputOnlyの場合にはマウスクリックなどのユーザー操作は無効ですが、Fullとすることで有効にすることもできます。


 以下が実行結果です。問題が解決されていることを確認できます。