注意,js调用C#,不一定在主线程上调用的,需要用SynchronizationContext
来切换到主线程
public class CSObj
{
private System.Threading.SynchronizationContext context;
public CSObj(System.Threading.SynchronizationContext context)
{
this.context = context;
}
public void ShowMsg(string msg)
{
System.Windows.MessageBox.Show(msg);
}
public void UpdateTime(string timeStr)
{
context.Send(x=> {
var window = App.Current.MainWindow as MainWindow;
window.lbTime.Content = timeStr;
},null);
}
}
坑已经在注释里面写明白了,一定不要再踩了
public MainWindow()
{
InitializeComponent();
//这个一定要开启,否则注入C#的对象无效
CefSharp.CefSharpSettings.LegacyJavascriptBindingEnabled = true;
//构造要注入的对象,参数为当前线程的调度上下文
var obj = new CSObj(System.Threading.SynchronizationContext.Current);
//注册C#对象
browser.JavascriptObjectRepository.Register("cs",obj,false,CefSharp.BindingOptions.DefaultBinder);
//html的路径一定要是绝对路径
string htmlPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.html");
browser.Address = htmlPath;
Unloaded += (sender, e) =>
{
Cef.Shutdown();
};
}
private void btnShowDev_Click(object sender, RoutedEventArgs e)
{
browser.ShowDevTools();
}
private void btnCallJS_Click(object sender, RoutedEventArgs e)
{
browser.GetMainFrame().ExecuteJavaScriptAsync("alert('cs')");
}
前台xaml代码:
<Window x:Class="CefsharpTest_20200709.MainWindow"
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"
xmlns:local="clr-namespace:CefsharpTest_20200709"
xmlns:cef="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Button x:Name="btnShowDev" Click="btnShowDev_Click">调试</Button>
<Button x:Name="btnCallJS" Click="btnCallJS_Click">调用JS方法</Button>
<Label HorizontalAlignment="Center" VerticalAlignment="Center">时间:</Label>
<Label Name="lbTime"></Label>
</StackPanel>
<cef:ChromiumWebBrowser Grid.Row="1" x:Name="browser"></cef:ChromiumWebBrowser>
</Grid>
</Window>
test.html:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<script>
function updateTime() {
var time = new Date().toLocaleTimeString();
//注意,CSObj中是public void UpdateTime(string timeStr),
//要转换为小写
cs.updateTime(time);
}
window.onload = function () {
document.getElementById("btnUpdate_time").onclick=function () {
setInterval(updateTime, 1000);
};
document.getElementById("btnShowCSharpWindow").onclick=function () {
alert("js窗口");
cs.showMsg("C#窗口");
};
};
</script>
</head>
<body>
<input type="button" id="btnShowCSharpWindow" value="弹C#框" />
<input type="button" id="btnUpdate_time" value="更新时间"/>
</body>
</html>
public class MenuHandler : IContextMenuHandler
{
public void OnBeforeContextMenu(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model)
{
//parameters.
model.Clear();
}
public bool OnContextMenuCommand(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags)
{
return false;
}
public void OnContextMenuDismissed(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame)
{
}
public bool RunContextMenu(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback)
{
return false;
}
}
在初始化时:
browser.MenuHandler = new MenuHandler();
public class DownloadHandler : IDownloadHandler
{
public void OnBeforeDownload(IWebBrowser chromiumWebBrowser, IBrowser browser, DownloadItem downloadItem, IBeforeDownloadCallback callback)
{
if (!callback.IsDisposed)
{
using (callback)
{
string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, downloadItem.SuggestedFileName);
callback.Continue(path, true);
}
}
}
public void OnDownloadUpdated(IWebBrowser chromiumWebBrowser, IBrowser browser, DownloadItem downloadItem, IDownloadItemCallback callback)
{
}
}
初始化的时候:
browser.DownloadHandler = new DownloadHandler();
var setting = new CefSettings();
setting.CefCommandLineArgs.Add("--ignore-urlfetcher-cert-requests", "1");
setting.CefCommandLineArgs.Add("--ignore-certificate-errors", "1");
Cef.Initialize(setting);