我正在构建一个应用程序,我为所有窗口和对话框创建了自定义外观;每个窗口的右上角都有一个自定义的“X”按钮等。我基本上设置WindowStyle = None和allowsTransparency = True。我在这个窗口中有一个选项卡控件,其中一个选项卡有一个WPF WebBrowser控件。当我刚开始时,我没有在窗口上自定义皮肤,并且Web浏览器控件按预期工作。一旦我对窗口进行了蒙皮并设置了AllowTransparency = True,并且WebBrowser控件现在只显示一个空白页面。
据我所知,ActiveX中存在某种导致此问题的缺陷,因为WebBrowser WPF控件本质上是一个包装器。有人可以为这个问题提供一个体面的解决方案或体面的解决方法吗?
以下是我的xaml和截图。为了这篇文章,我把它简化为一个简单的窗口:
此作品:( AllowTransparency = False)
<Window x:Class="AllowTransparencyIssue.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="500"
Width="700"
AllowsTransparency="False"
WindowStartupLocation="CenterScreen"
WindowStyle="SingleBorderWindow"
>
<Border BorderBrush="Blue" BorderThickness="3">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Row="0" HorizontalAlignment="Right" Click="Button_Click">Close Window</Button>
<TabControl Grid.Row="1">
<TabItem Header="StartPage.com">
<TabItem.Content>
<WebBrowser Source="http://www.startpage.com" />
</TabItem.Content>
</TabItem>
<TabItem Header="Google.com">
<TabItem.Content>
<WebBrowser Source="http://www.google.com" />
</TabItem.Content>
</TabItem>
<TabItem Header="Bing.com">
<TabItem.Content>
<WebBrowser Source="http://www.google.com" />
</TabItem.Content>
</TabItem>
</TabControl>
</Grid>
</Border>
</Window>
截图:
以下代码设置AllowTransparency = True和WindowStyle =无:
<Window x:Class="AllowTransparencyIssue.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="500"
Width="700"
AllowsTransparency="True"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
>
<Border BorderBrush="Blue" BorderThickness="3">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Row="0" HorizontalAlignment="Right" Click="Button_Click">Close Window</Button>
<TabControl Grid.Row="1">
<TabItem Header="StartPage.com">
<TabItem.Content>
<WebBrowser Source="http://www.startpage.com" />
</TabItem.Content>
</TabItem>
<TabItem Header="Google.com">
<TabItem.Content>
<WebBrowser Source="http://www.google.com" />
</TabItem.Content>
</TabItem>
<TabItem Header="Bing.com">
<TabItem.Content>
<WebBrowser Source="http://www.google.com" />
</TabItem.Content>
</TabItem>
</TabControl>
</Grid>
</Border>
</Window>
截图:
答案 0 :(得分:2)
我发现一篇文章似乎被冗余地复制并粘贴到了整个网络上。这篇帖子帮助了我解决了我的问题,但我决定对它进行改进并将它打包得更清洁。此外,当我在TabControl中使用它时,帖子中的原始代码不起作用。
以下是我发现的原始帖子的链接:
上面的解决方案要求创建一个Window,它在WindowsFormsHost对象中托管Windows窗体WebBrowser控件,该对象基本上将自己叠加在边框控件之上。
以下是我对解决方案的改进:
WebBrowserOverlayWindow.xaml:
<Window x:Class="AllowTransparencyIssue.WebBrowserOverlayWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WebBrowserOverlayWindow"
xmlns:winForms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
WindowStyle="None"
ShowInTaskbar="False"
ResizeMode="NoResize">
<WindowsFormsHost x:Name="wfh">
<winForms:WebBrowser x:Name="wfBrowser" />
</WindowsFormsHost>
</Window>
WebBrowserOverlayWindow.xaml.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace AllowTransparencyIssue
{
/// <summary>
/// Interaction logic for WebBrowserOverlayWindow.xaml
/// </summary>
public partial class WebBrowserOverlayWindow : Window
{
public WebBrowserOverlayWindow()
{
InitializeComponent();
}
public static readonly DependencyProperty TargetElementProperty = DependencyProperty.Register("TargetElement", typeof(FrameworkElement), typeof(WebBrowserOverlayWindow), new PropertyMetadata(TargetElementPropertyChanged));
public FrameworkElement TargetElement
{
get
{
return GetValue(TargetElementProperty) as FrameworkElement;
}
set
{
SetValue(TargetElementProperty, value);
}
}
public static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(string), typeof(WebBrowserOverlayWindow), new PropertyMetadata(SourcePropertyChanged));
public string Source
{
get
{
return GetValue(SourceProperty) as string;
}
set
{
SetValue(SourceProperty, value);
}
}
private static void SourcePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
var webBrowserOverlayWindow = sender as WebBrowserOverlayWindow;
if (webBrowserOverlayWindow != null)
{
webBrowserOverlayWindow.wfBrowser.Navigate(args.NewValue as string);
}
}
private static void TargetElementPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
var oldTargetElement = args.OldValue as FrameworkElement;
var webBrowserOverlayWindow = sender as WebBrowserOverlayWindow;
var mainWindow = Window.GetWindow(webBrowserOverlayWindow.TargetElement);
if (webBrowserOverlayWindow != null && mainWindow != null)
{
webBrowserOverlayWindow.Owner = mainWindow;
webBrowserOverlayWindow.Owner.LocationChanged += webBrowserOverlayWindow.PositionAndResize;
webBrowserOverlayWindow.TargetElement.LayoutUpdated += webBrowserOverlayWindow.PositionAndResize;
if (oldTargetElement != null)
oldTargetElement.LayoutUpdated -= webBrowserOverlayWindow.PositionAndResize;
webBrowserOverlayWindow.PositionAndResize(sender, new EventArgs());
if (webBrowserOverlayWindow.TargetElement.IsVisible && webBrowserOverlayWindow.Owner.IsVisible)
{
webBrowserOverlayWindow.Show();
}
webBrowserOverlayWindow.TargetElement.IsVisibleChanged += (x, y) =>
{
if (webBrowserOverlayWindow.TargetElement.IsVisible && webBrowserOverlayWindow.Owner.IsVisible)
{
webBrowserOverlayWindow.Show();
}
else
{
webBrowserOverlayWindow.Hide();
}
};
}
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
Owner.LocationChanged -= PositionAndResize;
if (TargetElement != null)
{
TargetElement.LayoutUpdated -= PositionAndResize;
}
}
private void PositionAndResize(object sender, EventArgs e)
{
if (TargetElement != null && TargetElement.IsVisible)
{
var point = TargetElement.PointToScreen(new Point());
Left = point.X;
Top = point.Y;
Height = TargetElement.ActualHeight;
Width = TargetElement.ActualWidth;
}
}
}
}
Generic.xaml ResourceDictionary(在&#34; Themes&#34;文件夹中):
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:AllowTransparencyIssue">
<Style TargetType="{x:Type local:TransparentWebBrowser}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TransparentWebBrowser}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
TransparentWebBrowser.cs(自定义控件):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace AllowTransparencyIssue
{
public class TransparentWebBrowser : Control
{
private WebBrowserOverlayWindow _WebBrowserOverlayWindow;
public static readonly DependencyProperty TargetElementProperty = DependencyProperty.Register("TargetElement", typeof(FrameworkElement), typeof(TransparentWebBrowser), new PropertyMetadata(TargetElementPropertyChanged));
public FrameworkElement TargetElement
{
get
{
return GetValue(TargetElementProperty) as FrameworkElement;
}
set
{
SetValue(TargetElementProperty, value);
}
}
public static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(string), typeof(TransparentWebBrowser), new PropertyMetadata(SourcePropertyChanged));
public string Source
{
get
{
return GetValue(SourceProperty) as string;
}
set
{
SetValue(SourceProperty, value);
}
}
private static void SourcePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
var transparentWebBrowser = sender as TransparentWebBrowser;
if (transparentWebBrowser != null)
{
transparentWebBrowser._WebBrowserOverlayWindow.Source = args.NewValue as string;
}
}
private static void TargetElementPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
var transparentWebBrowser = sender as TransparentWebBrowser;
if (transparentWebBrowser != null)
{
transparentWebBrowser._WebBrowserOverlayWindow.TargetElement = args.NewValue as FrameworkElement;
}
}
public TransparentWebBrowser()
{
_WebBrowserOverlayWindow = new WebBrowserOverlayWindow();
//TODO: Figure out how to automatically set the TargetElement binding...
//var targetElementBinding = new Binding();
//var rs = new RelativeSource();
//rs.AncestorType = typeof(Border);
//targetElementBinding.RelativeSource = rs;
//_WebBrowserOverlayWindow.SetBinding(TransparentWebBrowser.TargetElementProperty, targetElementBinding);
}
static TransparentWebBrowser()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(TransparentWebBrowser), new FrameworkPropertyMetadata(typeof(TransparentWebBrowser)));
}
}
}
修改后的MainWindow.xaml:
<Window x:Class="AllowTransparencyIssue.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:AllowTransparencyIssue"
Title="MainWindow"
Height="500"
Width="700"
AllowsTransparency="True"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
>
<Border BorderBrush="Blue" BorderThickness="3">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Row="0" HorizontalAlignment="Right" Click="Button_Click">Close Window</Button>
<TabControl Grid.Row="1">
<TabControl.Items>
<TabItem Header="StartPage.com">
<TabItem.Content>
<Border>
<local:TransparentWebBrowser TargetElement="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}}" Source="http://www.startpage.com" />
</Border>
</TabItem.Content>
</TabItem>
<TabItem Header="Google.com">
<TabItem.Content>
<Border>
<local:TransparentWebBrowser TargetElement="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}}" Source="http://www.google.com" />
</Border>
</TabItem.Content>
</TabItem>
<TabItem Header="Bing.com">
<TabItem.Content>
<Border>
<local:TransparentWebBrowser TargetElement="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}}" Source="http://www.bing.com" />
</Border>
</TabItem.Content>
</TabItem>
</TabControl.Items>
</TabControl>
</Grid>
</Border>
</Window>
屏幕截图证明这是有效的:
我对我的回答的最后想法和问题是,任何人都可以弄清楚如何在&#34; TransparentWebBrowser&#34;的实例构造函数中连接绑定代码。所以我不必在MainWindow.xaml中显式设置TargetElement属性???