首先,你需要创建一个自定义的BrowserRequestHandler
类,例如:
public class BrowserRequestHandler : IRequestHandler
{
public bool OnBeforeBrowse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, bool isRedirect)
{
if (!request.Url.StartsWith("file:"))
{
System.Diagnostics.Process.Start(request.Url);
return true;
}
return false;
}
public bool OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl,
WindowOpenDisposition targetDisposition, bool userGesture)
{
return false;
}
public bool OnCertificateError(IWebBrowser browserControl, IBrowser browser, CefErrorCode errorCode, string requestUrl,
ISslInfo sslInfo, IRequestCallback callback)
{
callback.Dispose();
return false;
}
public void OnPluginCrashed(IWebBrowser browserControl, IBrowser browser, string pluginPath)
{
throw new Exception("Plugin crashed!");
}
public CefReturnValue OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request,
IRequestCallback callback)
{
return CefReturnValue.Continue;
}
public bool GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port,
string realm, string scheme, IAuthCallback callback)
{
callback.Dispose();
return false;
}
public bool OnSelectClientCertificate(IWebBrowser browserControl, IBrowser browser, bool isProxy, string host, int port,
X509Certificate2Collection certificates, ISelectClientCertificateCallback callback)
{
callback.Dispose();
return false;
}
public void OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status)
{
throw new Exception("Browser render process is terminated!");
}
public bool OnQuotaRequest(IWebBrowser browserControl, IBrowser browser, string originUrl, long newSize,
IRequestCallback callback)
{
callback.Dispose();
return false;
}
public void OnResourceRedirect(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response,
ref string newUrl)
{
var url = newUrl;
newUrl = url;
}
public bool OnProtocolExecution(IWebBrowser browserControl, IBrowser browser, string url)
{
return url.StartsWith("mailto");
}
public void OnRenderViewReady(IWebBrowser browserControl, IBrowser browser)
{
}
public bool OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
{
return false;
}
public IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request,
IResponse response)
{
return null;
}
public void OnResourceLoadComplete(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request,
IResponse response, UrlRequestStatus status, long receivedContentLength)
{
}
}
这段代码中重要的部分是:
public bool OnBeforeBrowse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, bool isRedirect)
{
if (!request.Url.StartsWith("file:"))
{
System.Diagnostics.Process.Start(request.Url);
return true;
}
return false;
}
在我的情况下,我正在CEF中打开本地保存的HTML文件,如果这些本地保存的HTML文件有外部链接,它们将在默认浏览器中打开。
现在你已经创建了自定义的
BrowserRequestHandler
,你需要将其分配给浏览器。
如果你使用MVVM,你可以在你的模型中创建一个
BrowserRequestHandler
并将其分配给浏览器控件的
RequestHandler
依赖属性。但在我的情况下,由于我有几个浏览器实例在动态打开选项卡中,并且浏览器没有足够快地打开而抛出错误,所以存在时间问题。
因此,第二个选项是使用交互命名空间设置一个Loaded事件,如下所示:
<wpf:ChromiumWebBrowser Address="{Binding Html, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" x:Name="ChromiumWebBrowser">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding BrowserLoadedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</wpf:ChromiumWebBrowser>
在此之后,您可以将浏览器添加到您的视图模型中(或在管理类中完成此操作),并像以下代码一样将其RequestHandler
设置为您自定义的BrowserRequestHandler
:
browser.RequestHandler = new BrowserRequestHandler()
bool isRedirect
之前有一个bool userGesture
。 - Davis