当前位置:   article > 正文

WPF内嵌CEFSharp控件与JS交互_wpf cefsharp 网页 交互

wpf cefsharp 网页 交互

1)安装cefsharp.winform包

打开VS2017,新建WPF项目,打开nuget,找到cefsharp.winform,安装

 

1.为什么wpf程序不使用cefsharp.wpf?

因为cefwpf 49版本的bug很多,而winform_cef就比较靠谱,比如在不同的输入法切换后无法输入中文

2.那为什么不使用更高版本的cefwpf?

因为要支持XP,而49版本是cef_wpf能支持XP的最高版本

 

安装完后,需要将平台改成x64或者x86

因为Cefsharp没有针对AnyCpu的模式

 

Nuget如何处理引用关系?

接下来就不用做任何事情了,使用Nuget的好处是,微软把所有事都帮你干了,缺点就是,你不知道所有细节

我们不需要添加引用dll,只需要在代码中using Cefsharp;即可开始写代码了。

那么问题来了,到底nuget做了什么,没有引用就能直接使用cefsharp下面的一些文件dll

 

Nuget是通过package.config文件来控制需要添加的引用,该文件内容类似下图:

该文件位于源代码目录下,那么可以猜测,是用过该文件去寻找bin目录下的packages文件夹和下面的四个文件夹,

果不其然,bin下面确实存在四个文件,文件名就是 package id:

仔细检查这四个文件夹,可以看到每个文件夹下都有一个build文件夹

而build文件夹下面都有一个props的项目配置文件,我们打开其中一个:

 可以看到CefSharp.Winforms.props文件夹下面配置了相关的引用设置

可以看到文件中还会根据平台配置来选择判断添加哪些应用,如When,Otherwise等

 

而且build下面还有CefSharp.Common.targets 和CefSharp.Wpf.targets 这个俩个文件,估计也是来保证输出目录里面有必要的所需文件吧

 

 

与JS交互完整代码如下:

  1. public partial class MainWindow : Window
  2. {
  3. public MainWindow()
  4. {
  5. InitializeComponent();
  6. //***这段代码很关键,而且只需执行一次即可,最好写在静态构造函数中*** //
  7. var settings = new CefSharp.CefSettings();
  8. settings.CefCommandLineArgs.Add("disable-gpu", "1");
  9. settings.CefCommandLineArgs.Add("force-device-scale-factor", "2");
  10. Cef.Initialize(settings);
  11. //********************************************************* //
  12. var webbrowser = new ChromiumWebBrowser("https://www.baidu.com");
  13. //为什么要用一个windowsformhost包起来,因为cef是winform的,所以在wpf下使用,必须用这个包一下
  14. var winform = new WindowsFormsHost()
  15. {
  16. Child = webbrowser
  17. };
  18. //绑定,和js交互的关键,注册一个JsObj,这个可以自定义,然后对于js来说,第二个参数this就代表了JsObj
  19. webbrowser.RegisterAsyncJsObject("JsObj", this, false);
  20. this.Content = winform;
  21. }
  22. public void (object pramas)
  23. {
  24. //可以通过这种方式取得参数
  25.  var type = pramas.GetType();
  26. var id=type.InvokeMember("id", System.Reflection.BindingFlags.GetProperty, null, pramas, null);
  27. //do something.....
  28. Application.Current.MainWindow.Dispatcher.BeginInvoke(new Action(() =>//报错
  29. {
  30. //do something.....
  31. }));
  32. Dispatcher.BeginInvoke(new Action(() => //不会报错
  33. {
  34. //do something.....
  35. }));
  36. }
  37. }

上方代码中,display是被调方法,在执行display时,是子线程在执行,聪明的你一定想到了

那就Application.Current.MainWindow.Dispather.BeginInvoke,但是依然会报错,为什么?

因为在get mainwindow时依旧是操作了主线程的UI元素,所以改成下面那种方式即可

js代码:

  1. <script type="text/javascript">
  2. function abc()
  3. {
  4. JsObj.display(data);
  5. }
  6. </script>

 

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/257836
推荐阅读
相关标签
  

闽ICP备14008679号