wpf webBrowser控件
wpf webBrowser 的控件 坑太多了 不推荐使用, 推荐使用winform webbrowser
在wpf中如何使用与扩展winform webbrowser,请看我的另一篇文章在wpf中使用winform webbrowser
介绍
WebBrowsers可以让我们在窗体中进行导航网页。
WebBrowser控件内部使用ie的引擎,因此使用WebBrowser我们必须安装ie浏览器(windows默认安装的)。
使用
直接在xmal中使用webBrowser控件
1 | <WebBrowser x:Name= "WebBrowser1" Source = "xxx.com" ></WebBrowser> |
其中Source熟悉可以将webBrowser控件指向一个网页(也可以是本地文件的绝对路径)
除了使用Source属性还有以下方法进行导航:
方法 用法
Navigate() 传入网页url WebBrowser1.Navigate(new Uri(address));
NavigateToString 传入html页面内容WebBrowser1.NavigateToString("<html><body></body></html > ");
GoBack() 导航到上一个文档,需要判断能否调用if (WebBrowser1.CanGoBack){WebBrowser1.GoBack();}
GoForward 导航到下一个文档if (WebBrowser1.CanGoForward){WebBrowser1.GoForward();}
Navigating 发生在导航到新的页面时发生,可以在这里取消导航 WebBrowser1.Navigating += (sender, args) ={args.Cancel = true;};
Navigated 导航之后,在下载web页面之前引发 WebBrowser1.Navigated += (sender, args) =>{Console.WriteLine("ed" + args?.Uri);};
LoadCompleteed 当web页面下载完成时引发这个事件,这时可以处理网页 WebBrowser1.LoadCompleted += (sender, args)=>{Console.WriteLine(WebBrowser1.Document);};
问题js报错
默认情况下webBrowser用的是比较低的ie内核,这样如果访问的网页有不支持的脚本或者其他问题,就会没有办法正常运行,比如报错 javaScript错误。某些情况下使用ie可以打开的网页,在webBrowser需要管理员权限才可以正常打开,没有管理员权限也会报jabaScript错误。所以一般使用winForm的webBrowser,方便扩展,并且资料多。
避免报错不弹提示框
1 2 3 4 | WebBrowser1.Navigated += (sender, args) => { SetSilent(wbMain, true ) } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public static void SetSilent(WebBrowser browser, bool silent) { if (browser == null ) throw new ArgumentNullException( "browser" ); // get an IWebBrowser2 from the document IOleServiceProvider sp = browser.Document as IOleServiceProvider; if (sp != null ) { Guid IID_IWebBrowserApp = new Guid( "0002DF05-0000-0000-C000-000000000046" ); Guid IID_IWebBrowser2 = new Guid( "D30C1661-CDAF-11d0-8A3E-00C04FC9E26E" ); object webBrowser; sp.QueryService( ref IID_IWebBrowserApp, ref IID_IWebBrowser2, out webBrowser); if (webBrowser != null ) { webBrowser.GetType().InvokeMember( "Silent" , BindingFlags.Instance | BindingFlags.Public | BindingFlags.PutDispProperty, null , webBrowser, new object [] { silent }); } } } [ComImport, Guid( "6D5140C1-7436-11CE-8034-00AA006009FA" ), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IOleServiceProvider { [PreserveSig] int QueryService([In] ref Guid guidService, [In] ref Guid riid, [MarshalAs(UnmanagedType.IDispatch)] out object ppvObject); } |
这种只是让它不出现报错窗口,不能从根本上解决。
修改注册表使用新的ie内核,下面是代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | static void SetWebBrowserFeatures( int ieVersion) { if (LicenseManager.UsageMode != LicenseUsageMode.Runtime) return ; var appName = System.IO.Path.GetFileName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName); UInt32 ieMode = GeoEmulationModee(ieVersion); var featureControlRegKey = @"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\" ; Registry.SetValue(featureControlRegKey + "FEATURE_BROWSER_EMULATION" , appName, ieMode, RegistryValueKind.DWord); Registry.SetValue(featureControlRegKey + "FEATURE_ENABLE_CLIPCHILDREN_OPTIMIZATION" , appName, 1, RegistryValueKind.DWord); } static UInt32 GeoEmulationModee( int browserVersion) { UInt32 mode = 11000; // Internet Explorer 11. Webpages containing standards-based !DOCTYPE directives are displayed in IE11 Standards mode. switch (browserVersion) { case 7: mode = 7000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode. break ; case 8: mode = 8000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode. break ; case 9: mode = 9000; // Internet Explorer 9. Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode. break ; case 10: mode = 10000; // Internet Explorer 10. break ; case 11: mode = 11000; // Internet Explorer 11 break ; } return mode; } |
比如你想使用最新的IE11
1 | SetWebBrowserFeatures(11); |
在网页中强制以ie最高级别的可用模式显示内容
1 | <meta http-equiv= "X-UA-Compatible" content= "edge" /> |
内存泄漏
Memory leak when using WPF WebBrowser control in multiple windows
内存泄漏的解决方式
不使用wpf中的 WebBrowser
将WebBrowser放到子进程中,每次开关都会重新分配内存
删除掉所有引用,来清理内存泄漏。关闭窗口时调用下面代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | public void Dispose() { webBrowser.Dispose(); var window = GetWindowElement(webBrowser); if (window == null ) return ; var field = typeof (Window).GetField( "_swh" , BindingFlags.NonPublic | BindingFlags.Instance); var valueSwh = field.GetValue(window); var valueSourceWindow = valueSwh.GetType().GetField( "_sourceWindow" , BindingFlags.Instance | BindingFlags.NonPublic).GetValue(valueSwh); var valuekeyboardInput = valueSourceWindow.GetType().GetField( "_keyboardInputSinkChildren" , BindingFlags.Instance | BindingFlags.NonPublic).GetValue(valueSourceWindow); var inputSites = valuekeyboardInput as IEnumerable<IKeyboardInputSite>; if (inputSites == null ) return ; var currentSite = inputSites.FirstOrDefault(s => ReferenceEquals(s.Sink, webBrowser)); if (currentSite != null ) currentSite.Unregister(); } private static Window GetWindowElement(DependencyObject element) { while (element != null && !(element is Window)) { element = VisualTreeHelper.GetParent(element); } return element as Window; } |
原文链接:https://blog.csdn.net/wodeshijianhrf/article/details/79907743
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!