随着 Silverlight 4.0 的发布,引入了 WebBrowser 控件。但是,它仅设计用于“Out Of Browser”应用程序。但是,随着 Silverlight 5 的发布,该控件也可以在“浏览器内”受信任的应用程序中使用。
自 Silverlight 中引入 WebBrowser 控件以来,许多开发人员一直在使用它在应用程序中显示 HTML 内容。但是,主要的限制是“空域”问题。
在应用程序窗口中,窗口中的每个像素仅属于一个 HWND,它构成了该 HWND 的空域。HWND 只能在属于它的那些像素上渲染。
在典型的 Silverlight OOB 应用程序中,只有一个 Silverlight-HWND。因此,Silverlight 应用程序中的整个像素都属于这个 HWND,并且构成了它的空域。
但是,在我们的场景中,当我们在 Silverlight OOB 应用程序中引入 WebBrowser 控件时,Airspace 由 WebBrowser 控件的 HWND 共享。这就是众所周知的空域问题。
WebBrowser 控件所在的像素将属于 WebBrowser-HWND。因此,Silverlight 将无法在属于其他 HWND 的像素上渲染任何内容。
这个问题是因为;Silverlight 中可用的 WebBrowser 控件是“System.Windows.Controls.WebBrowser”控件的包装。其他 Silverlight 控件不会为自己创建新窗口;相反,它将在单个 HWND 下创建。WebBrowser 控件不是真正的 Silverlight 控件,而是 Windows HTML 控件的包装器。这些本机控件将创建自己的 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 控件中的更改不会自动反映,除非重新绘制。
这是一个简单的解决问题的方法,如果设计得当,考虑到我们的限制,它会起作用。