Silverlight 4.0のリリースで、WebBrowserコントロールが導入されました。ただし、「ブラウザ外」アプリケーションでのみ使用するように設計されています。ただし、Silverlight 5のリリースでは、このコントロールは「ブラウザー内」の信頼できるアプリケーションでも使用できます。
SilverlightにWebBrowserコントロールが導入されて以来、多くの開発者がWebBrowserコントロールを使用してアプリケーション内のHTMLコンテンツを表示してきました。しかし、主な制限は「空域」の問題です。
アプリケーションウィンドウでは、ウィンドウ内の各ピクセルは1つのHWNDにのみ属し、そのHWNDの空域を構成します。HWNDは、それに属するピクセルでのみレンダリングできます。
一般的なSilverlightOOBアプリケーションでは、Silverlight-HWNDは1つだけです。したがって、Silverlightアプリケーションのピクセル全体がこのHWNDに属し、そのための空域を構成します。
ただし、Silverlight OOBアプリケーションにWebBrowserコントロールを導入するシナリオでは、AirspaceはWebBrowserコントロールのHWNDによって共有されます。そして、それは空域問題として知られています。
WebBrowserコントロールが存在するピクセルは、WebBrowser-HWNDに属します。そのため、Silverlightは、他のHWNDに属するピクセル上で何もレンダリングできなくなります。
この問題は次の理由によるものです。Silverlightで使用可能なWebBrowserコントロールは、「System.Windows.Controls.WebBrowser」コントロールのラッパーです。他のSilverlightコントロールは、それ自体に新しいウィンドウを作成しません。むしろ、単一のHWNDの下で作成されます。WebBrowserコントロールは、実際のSilverlightコントロールではなく、WindowsHTMLコントロールのラッパーです。これらのネイティブコントロールは、独自のHWNDを作成します。
このため、WebBrowserコントロールは、アプリケーション内の他のコントロールと常にオーバーラップします。たとえば、固定ヘッダーとスクロール機能を備えたページが使用されている場合、またはWebBrowserコントロールがメニューコントロールの下に配置されている場合です。他のインスタンスが存在する可能性があります。
「WebBrowserBrush」を使用することで、この問題を解決できます。
WebBrowserBrushはWebBrowserコントロールとともに導入され、リッチHTMLコンテンツを表示するために連携して動作するように設計されています。
WebBrowserBrushは、HTMLコンテンツで領域をペイントするBrushオブジェクトの一種です。このHTMLコンテンツは、WebBrowserコントロールによって提供されます。他の種類のブラシと同様に、WebBrowserBrushを使用して、長方形、パスのジオメトリコンテンツなどを塗りつぶすことができます。
では、このブラシはこの問題の解決にどのように役立つのでしょうか。
この問題を解決するには、WebBrowserを非表示にし、WebBrowserBrushを使用してWebBrowserのHTMLコンテンツで領域をペイントします。WebBrowserBrushは、HTMLコンテンツを他のコントロールと同じレイヤーにペイントし、他のコントロールをその上に表示できるようにします。必要なときにWebBrowserコントロールを表示できます。考慮する必要があるのは、このロジックを処理するための適切なイベントを見つけることだけです。
以下のサンプルアプリケーションでは、コンボボックスリストを開いたときにWebBrowserの上にレンダリングしたいと思います。ロジックを処理するためにComboBox_DropDownChangedイベントを使用しました。リストが開いているときは、WebBrowserコントロールを非表示にして、その領域をWebBrowserBrushでペイントします。次に、リストを閉じたときにコントロールを戻します。
> <UserControl x:Class="SilverlightApplication1_WebBrowser.MainPage"
> xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
> xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
> xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
> <Grid x:Name="LayoutRoot" Background="White"
> HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
> <Canvas HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
> <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
> <Grid.RowDefinitions> <RowDefinition Height="50"
> /> <RowDefinition Height="50" />
> <RowDefinition Height="Auto" /> </Grid.RowDefinitions>
> <Grid.ColumnDefinitions> <ColumnDefinition
> Width="*"/> <ColumnDefinition Width="50"/>
> </Grid.ColumnDefinitions> <ComboBox
> Canvas.ZIndex="10" Grid.Row="0" x:Name="cbTestList"
> DropDownOpened="cbTestList_DropDownOpened"
> DropDownClosed="cbTestList_DropDownClosed" >
> <ComboBox.Items> <ComboBoxItem Content="--
> Select --" IsSelected="True"/> <ComboBoxItem
> Content="Text1"/> <ComboBoxItem
> Content="Text2"/> <ComboBoxItem
> Content="Text3"/> <ComboBoxItem
> Content="Text4"/> <ComboBoxItem
> Content="Text5"/> <ComboBoxItem
> Content="Text6"/> <ComboBoxItem
> Content="Text7"/> <ComboBoxItem
> Content="Text8"/> <ComboBoxItem
> Content="Text9"/> <ComboBoxItem
> Content="Text10"/> <ComboBoxItem
> Content="Text11"/> <ComboBoxItem
> Content="Text12"/> <ComboBoxItem
> Content="Text13"/> <ComboBoxItem
> Content="Text14"/> <ComboBoxItem
> Content="Text15"/> </ComboBox.Items>
> </ComboBox>
> <WebBrowser x:Name="wb" Height="500" Width="800" Grid.Column="0"
> Grid.ColumnSpan="2" Grid.Row="2"
> Canvas.ZIndex="0" HorizontalAlignment="Stretch"
> VerticalAlignment="Stretch" />
> <TextBox x:Name="txtUrl" Margin="10" Grid.Row="1" Grid.Column="0"
> Canvas.ZIndex="10"/> <Button Grid.Column="1"
> Grid.Row="1" Margin="10" Canvas.ZIndex="10" Content="Go"
> Name="btnLoadContent" Click="btnLoadContent_Click" />
> <Rectangle Grid.Column="0" Height="500" Width="800"
> Grid.ColumnSpan="2" Grid.Row="2"
> HorizontalAlignment="Stretch"
> VerticalAlignment="Stretch"> <Rectangle.Fill>
> <WebBrowserBrush SourceName="wb" x:Name="WBB1"/>
> </Rectangle.Fill> </Rectangle> </Grid>
> </Canvas> </Grid> </UserControl>
WebBrowserBrushとWebBrowserコントロールを使用して問題を解決することはできますが、考慮しなければならない制限がいくつかあります。
1.ユーザーはWebBrowserBrushを操作できません。
2. WebBrowserコントロールの変更は、再描画しない限り自動的に反映されません。
これは問題の簡単な回避策であり、適切に設計されていれば、制限を考慮して機能します。