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

时间:2012-09-13 10:52:42

标签: silverlight webbrowser-control 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>

1 个答案:

答案 0 :(得分:1)

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

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

在应用程序窗口中,窗口中的每个像素恰好只属于一个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控件中的更改不会自动反映。

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