Можно ли визуализировать элементы 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 не будут отражаться автоматически, если не будут перерисованы.
Это простое решение проблемы, и оно будет работать, если разработано правильно, учитывая имеющиеся у нас ограничения.