是否可以在Web浏览器控件的顶部呈现Silverlight元素(在OOB模式下)



我希望能够使用其他Silverlight元素和各种转换来隐藏和显示Web浏览器控件。

任何Web浏览器控件似乎总是呈现在页面的最后一个。有什么方法可以让其他元素在Web浏览器上呈现吗?

下面是一个显示问题的最小XAML示例:

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="BrowserSilverlightApplication.MainPage"
    Width="640" Height="480">
    <Grid x:Name="LayoutRoot" Background="White">
        <WebBrowser x:Name="webBrowser" Margin="16" Loaded="WebBrowser_Loaded"/>
        <Rectangle Fill="#447171DE" Margin="8" Stroke="Black" IsHitTestVisible="False" StrokeThickness="0">
            <Rectangle.Effect>
                <BlurEffect Radius="18"/>
            </Rectangle.Effect>
        </Rectangle>
    </Grid>
</UserControl>

随着Silverlight 4.0的发布,引入了WebBrowser控件。但是,它的设计仅用于"浏览器外"应用程序。但是,随着Silverlight 5的发布,该控件也可以在"浏览器内"受信任的应用程序中使用。

自从在Silverlight中引入WebBrowser控件以来,许多开发人员一直在使用它来显示应用程序中的HTML内容。但是,主要的限制是"空域"问题。

在应用程序窗口中,窗口中的每个像素恰好只属于一个HWND,该HWND构成该HWND的空域。HWND只能在属于它的像素上进行渲染。

在一个典型的Silverlight OOB应用程序中,只有一个Silverlight HWND。因此,Silverlight应用程序中的所有像素都属于这个HWND,这构成了它的空间。

但是,在我们的场景中,当我们在Silverlight OOB应用程序中引入WebBrowser控件时,空域由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是一种Brush对象,它用HTML内容绘制区域。此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控件中的更改不会自动反映。

这是一个简单的解决问题的方法,如果设计得当,考虑到我们的局限性,它会起作用。

最新更新