UWP开发之控件:用WebView做聊天框
目录
大家都知道,无论是之前的Winform、WPF还是现在的IOS、Android开发中,都存在一个极其牛茶但是被很多人用错了的控件:Web浏览控件。各个平台中的叫法不同,但是作用类似:能够加载显示HTML。UWP开发中同样存在这样的一个控件:WebView。往大了说,用它可以做一个简单浏览器,但是这篇博客并不打算教大家怎样用它开发一款UWP浏览器,因为我认为它存在的价值并不在此。当然了,你要是非要这样去做,也是可以的,看微软官方的Demo:https://microsoftedge.github.io/JSBrowser/(用WebView,Js语言开发的UWP浏览器)。
源码先上来:https://github.com/sherlockchou86/Blogs/tree/master/ChatBoxbyWebView
需要先看效果图的猛戳这里。
(1).前面说过,WebView可以加载显示HTML。这里的HTML包括Internet上的资源(比如直接定位到http://www.cnblogs.com),当然也包括本地资源,比如我在APP中使用代码现场生成一串HTML,然后让WebView去渲染呈现。大家知道HTML在界面表现方面非常出众,并且扩展性强,那么使用WebView+HTML(CSS、JS)做出来的UI肯定非常不错,我认为这是WebView被忽略的价值之一。
(2).另外,现在流行的Hybrid APP(Native代码+Web),其基础便是WebView这种能够呈现HTML的控件,不管是IOS还是Android中都有类似功能的控件作为HTML的容器,它们主要的功能就是加载并显示APP中的Web页面。与前(1)中讲的不同的是,这里的HTML页面是你自己开发并且部署到服务器上的,有关更多的介绍大家可以网上搜索Hybrid APP。由于这不是本文的重点,所以不多讲了。
不管是(1)中加载本地HTML还是(2)中加载自己服务器上的HTML页面,都会涉及到一个问题,那就是Native代码(C#)怎样与WebView中的JS进行通信,很明显,Native代码掌握整个APP的控制权,它应该可以控制WebView中HTML的显示方式,当用户操作WebView时(比如点击按钮),Native代码也应该知道。所以,在使用WebView时,通信是关键。
(1)明白WebView的作用,前面已经说过了,不要把它当做是一个普通的浏览器;
(2)C#与WebView中的JS通信
其实很简单,WebView控件有WebView.InvokeScriptAsync(...)方法,使用它可以调用JS中的任何方法,比如我要设置博客园登录页面中用户名、密码输入框的的值,我们可以这样做:
LoginWebView.Navigate(new Uri("http://www.cnblogs.com/")); //加载博客园登录页面
string js=""; //构建脚本
js += "document.getElementById('input1').setAttribute('value','" + UserName.Text + "');"; //设置用户名
js += "document.getElementById('input2').setAttribute('value','" + PassWord.Password + "');"; //设置密码
js += "document.getElementById('signin').click();"; //点击登录
await LogintWebView.InvokeScriptAsync("eval", new string[] { js }); //eval函数大家都知道,就是执行一段字符串
如上所示,使用InvokeScriptAsync方法调用eval这个JS函数。
(3)WebView中的JS和C#通信
这个有个前提:WebView中HTML(JS)必须是你自己写的,换句话说,WebView加载的内容必须是你能控制的,否则很难监听到WebView中的代码动向,如果你加载博客园的登录页面,你想在用户点击登录的时候干点啥,呵呵,很难,因为博客园的登录页面不是你写的。那么如果加载的页面是你自己写的,那么怎样与C#通信呢?其实这个也简单,在需要通信的地方,我们使用这个JS代码:window.external.notify("...");然后我们C#中注册WebView的ScriptNotify事件,那么就可以在C#中收到JS传过来的字符串了(注意只能是string类型,因为两者数据类型不一样)。具体的代码请看我后面给出的示例。
(4)插入脚本
当你通过WebView访问一个外部网站,想要在页面中注入自己写的脚本,做不到。只能现将页面HTML下载下来保存成本地资源,然后再插入脚本,然后再使用WebView.NavigateToString("html")方法加载本地资源。做不到的原因很简单,大家都懂。
光说不练假把式,要证明我说的是真的,可以一信,那么接下来我给大家看一个使用WebView做的聊天框。只加载本地HTML(CSS、JS),涉及到了C#与JS之间的相互通信。代码已上传到github,有需要的同学可以下下来看一下,下面是界面:
细节地方还需要完善,如果有要用的机会,下下来一定要自己完善一下。另外,上个礼拜写的博客园UWP版 PC版马上就做完了,等做完源码马上传上来,感兴趣的可以关注一下。开源有益。:)