我试图在XAML / WPF应用程序中评估CefSharp是否适用于我们。
目前,我们正在使用MS的WebBrowser,它有严重的限制。
我们的应用程序中有一个窗口,它显示多个自定义控件之一,其中一个包含一个浏览器控件,用于加载包含地图的网页。
为了进行测试,我创建了一个自定义控件,其中包含一个硬编码为http://www.google.com的WebBrowser。
然后我创建了第二个自定义控件,其中包含一个硬编码为http://www.google.com的ChromiumWebBrowser。
我对代码中的浏览器控件一无所知,我只是简单地制作用于将它们包装起来或折叠的用户控件。
但是如果我在XAML中包含ChromiumWebBrowser,无论我是否可见,退出时我都会遇到异常:
System.InvalidOperationException was unhandled
Message: An unhandled exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll
Additional information: The calling thread cannot access this object because a different thread owns it.
为了说清楚,如果我的自定义控件包含这个,我不会得到例外:
<KtWpf:KorUserControl
x:Class="KtWpf.CEFSharpUtilityMap"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:KtWpf="clr-namespace:KtWpf" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"
>
<DockPanel>
<TextBox DockPanel.Dock="Top">CEFSharp</TextBox>
<WebBrowser
x:Name="mapBrowser"
Source="http://www.google.com"
/>
</DockPanel>
</KtWpf:KorUserControl>
如果它包含这个,我会这样做:
<KtWpf:KorUserControl
x:Class="KtWpf.CEFSharpUtilityMap"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:cefSharp="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
xmlns:KtWpf="clr-namespace:KtWpf" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"
>
<DockPanel>
<TextBox DockPanel.Dock="Top">CEFSharp</TextBox>
<cefSharp:ChromiumWebBrowser
x:Name="mapBrowser"
Address="http://www.google.com"
/>
</DockPanel>
</KtWpf:KorUserControl>
有什么想法吗?
我正在使用NuGet的CefSharp.Wfp版本49.0.0。 (还有CefSharp.Common和cef.redist.x64,虽然我为x86做了同样的事情。)
===添加callstack ===
> WindowsBase.dll!System.Windows.Threading.Dispatcher.VerifyAccess() Unknown
PresentationCore.dll!MS.Internal.Media.VisualTreeUtils.AsVisual(System.Windows.DependencyObject element, out System.Windows.Media.Visual visual, out System.Windows.Media.Media3D.Visual3D visual3D) Unknown
PresentationCore.dll!MS.Internal.Media.VisualTreeUtils.AsNonNullVisual(System.Windows.DependencyObject element, out System.Windows.Media.Visual visual, out System.Windows.Media.Media3D.Visual3D visual3D) Unknown
PresentationCore.dll!System.Windows.Media.VisualTreeHelper.GetParent(System.Windows.DependencyObject reference) Unknown
PresentationCore.dll!System.Windows.Media.Visual.ClearTreeBits(System.Windows.DependencyObject e, System.Windows.Media.VisualFlags treeFlag, System.Windows.Media.VisualFlags nodeFlag) Unknown
PresentationCore.dll!System.Windows.Media.Visual.VisualAncestorChanged.remove(System.Windows.Media.Visual.AncestorChangedEventHandler value) Unknown
PresentationCore.dll!System.Windows.PresentationSource.RemoveSourceChangedHandler(System.Windows.IInputElement e, System.Windows.SourceChangedEventHandler handler) Unknown
CefSharp.Wpf.dll!CefSharp.Wpf.ChromiumWebBrowser.Dispose(bool isdisposing) Unknown
CefSharp.Wpf.dll!CefSharp.Wpf.ChromiumWebBrowser.Dispose() Unknown
CefSharp.Core.dll!CefSharp.Cef.Shutdown() Unknown
CefSharp.Core.dll!CefSharp.Cef.ParentProcessExitHandler(object sender, System.EventArgs e) Unknown
答案 0 :(得分:0)
我们需要做的是控制初始化和关闭。
在App.OnStartup()中:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
Cef.Initialize();
...
}
App.OnExit()中的:
protected override void OnExit(ExitEventArgs e)
{
Cef.Shutdown();
base.OnExit(e);
}