Можно ли визуализировать элементы Silverlight поверх элемента управления веб-браузера (в режиме OOB)

Я хотел бы иметь возможность скрывать и открывать элементы управления веб-браузера, используя другие элементы Silverlight и различные переходы.

Похоже, что любые элементы управления веб-браузера всегда отображаются в последнюю очередь на странице. Есть ли способ получить другие элементы для рендеринга поверх веб-браузера?

Вот минимальный пример 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 ответ

С выпуском Silverlight 4.0 был представлен элемент управления WebBrowser. Но он был разработан только для использования в приложении Out Of Browser. Однако с выпуском Silverlight 5 элемент управления также можно использовать в доверенном приложении "в браузере".

С момента появления элемента управления WebBrowser в Silverlight многие разработчики используют его для отображения содержимого HTML внутри приложения. Но основным ограничением является проблема "воздушного пространства".

В окне приложения каждый пиксель в окнах принадлежит только одному HWND, который составляет воздушное пространство для этого HWND. HWND может рендерить только те пиксели, которые ему принадлежат.

В типичном приложении Silverlight OOB будет только один Silverlight-HWND. Таким образом, все пиксели в приложении Silverlight принадлежат этому HWND, и это составляет воздушное пространство для этого.

Но в нашем сценарии, когда мы представляем элемент управления WebBrowser в нашем приложении Silverlight OOB, воздушное пространство совместно используется HWND элемента управления WebBrowser. И это известно как проблема воздушного пространства.

Пиксели, в которых находится элемент управления WebBrowser, будут принадлежать WebBrowser-HWND. Таким образом, Silverlight не сможет ничего визуализировать на пикселе, который принадлежит другому HWND.

Эта проблема потому что; элемент управления WebBrowser, доступный в Silverlight, является оболочкой для элемента управления "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, чтобы закрасить область HTML-контентом из WebBrowser. WebBrowserBrush закрасит содержимое HTML в том же слое, что и другие элементы управления, и позволит отображать над ним другие элементы управления. Мы можем показать элемент управления 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 не будут отражаться автоматически, если не будут перерисованы.

Это простое решение проблемы, и оно будет работать, если разработано правильно, учитывая имеющиеся у нас ограничения.

Другие вопросы по тегам