2014年09月02日更新

今天用了一下WebBrowser,在使用过程中也遇到了一些问题,在这里做一下记录

虽然WebBrowser比较重,会比较影响性能(除非一定要用到它,否则尽量少用),但有时候还是得用WebBrowser来作为显示的控件,比如WP上有2048渲染的限制,我们可以通过WebBrowser来显示长文本,还有富文本信息(新闻)等,但使用起来也并不方便,这里做一下记录

1、禁止缩放  

    <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--这里禁止缩放-->
<meta content="width=device-width,user-scalable=no" name="viewport"> <style type="text/css">
img {
width: 100%;
}
</style>
</head>

2、JS调用C#代码(Notify)

  我们可以在JS中发送一个消息到后台代码,告知需要做什么操作

    比如在页面中有一个电话号码,当用户点击的时候,我们需要调用系统的API调用电话的Task,或者发邮件功能,又或者比较常见的,我们希望点击页面里面的图片的时候可以显示一张大图,并可以保存图片

  1)由于JS只能向后台代码发送字符串消息,为了区分不同的消息,我们先统一一下消息格式

    /// <summary>
/// JS消息格式
/// </summary>
public class JsInvokeModel
{
[JsonProperty("type")]
public string Type { get; set; } [JsonProperty("content1")]
public string Content1 { get; set; } [JsonProperty("content2")]
public string Content2 { get; set; } [JsonProperty("content3")]
public string Content3 { get; set; }
}

  2)Xaml

<phone:WebBrowser x:Name="Browser" Grid.Row="" IsScriptEnabled="True" ScriptNotify="Browser_OnScriptNotify" LoadCompleted="Browser_OnLoadCompleted" Source="http://www.baidu.com" />

  3、.cs:JS通知事件函数

    private void Browser_OnScriptNotify(object sender, NotifyEventArgs e)
{
//这个事件函数可以监听到JS通知的消息,消息类型为文本
//这里统一消息格式为:JsInvokeModel
var model = JsonConvert.DeserializeObject<JsInvokeModel>(e.Value);
switch (model.Type)
{
case "phoneCall":
PhoneCall(model.Content1, model.Content2);
break;
case "sendEmail":
SendEmail(model.Content1, model.Content2, model.Content3);
break;
case "image":
MessageBox.Show(string.Format("图片:{0}", model.Content1));
break;
case "text":
MessageBox.Show(string.Format("文本:{0}", model.Content1));
break;
}
} public void SendEmail(string to, string body, string subject)
{
var task = new EmailComposeTask
{
Body = body,
To = to,
Subject = subject,
};
task.Show();
} public void PhoneCall(string name, string phone)
{
var task = new PhoneCallTask { DisplayName = name, PhoneNumber = phone };
task.Show();
}

  4)示例文件(HTML)

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--这里禁止缩放-->
<meta content="width=device-width,user-scalable=no" name="viewport"> <style type="text/css">
img {
width: 100%;
}
</style>
</head>
<body>
<div id="content">
<a onclick="phoneCall('中国移不动', '10086')">打电话</a>
<br/>
<a onclick="invokeText('js调用C#方法')">Invoke C#</a>
<br />
<a onclick="sendEmail('zhengbomo@hotmail.com', '测试邮件,从WebBrowser调用', '测试')">发邮件</a>
<br />
<br /> <div>普通文本普通文本普通文本普通文本普通文本普通文本普通文本普通文本普通文本普通文本普通文本</div> <!--图片-->
<img src="http://s1.dwstatic.com/group1/M00/F3/AD/9c26c21d6111fe1e2c2d9b301ad2fe66.jpg" alt="" />
<img src="http://s1.dwstatic.com/group1/M00/E0/E7/a43758af471383c14f2706e8b4cf2633.jpg" alt="" />
<img src="http://s1.dwstatic.com/group1/M00/B4/F7/f3cbe9a238c60807ea3cd82e3252e2a3.jpg" alt="" /> <!--引用安装目录的资源-->
<img src="../emoji1.png" alt="" /> <!--引用本地文件-->
<img src="x-wmapp0:Assets/AlignmentGrid.png" alt="" />
</div> <!--引用本地js-->
<script src="../../Scripts/json2.min.js"></script>
<!--<script src="x-wmapp0:Scripts/json2.min.js"></script>-->
<script type="text/javascript">
window.onload = function () { //动态加载Script
//var myScript = document.createElement("script");
//myScript.type = "text/javascript";
//myScript.src = "x-wmapp0:Scripts/json2.min.js";
//document.body.appendChild(myScript); var imgs = document.getElementsByTagName("img");
for (var i = 0, len = imgs.length; i < len; i++) {
imgs[i].onclick = function (e) {
var jsonObj = { type: 'image', content1: this.src };
notify(JSON.stringify(jsonObj));
};
}
}; //给C#后台代码调用的方法
function InvokeFromCode() {
alert("C#调用js不参数的方法");
} //给C#后台代码调用的方法
function InvokeFromCodeWithParam(text) {
document.getElementById("content").innerHTML = text;
return "15";
} //发送文本消息
function invokeText(text) {
var jsonObj = { type: 'text', content1: text };
notify(JSON.stringify(jsonObj));
} //发送邮件
function sendEmail(to, body, subject) {
var jsonObj = { type: 'sendEmail', content1: to, content2: body, content3: subject };
notify(JSON.stringify(jsonObj));
} //调用打电话的方法
function phoneCall(name, phone) {
//序列化方法
var jsonObj = { type: 'phoneCall', content1: name, content2:phone };
notify(JSON.stringify(jsonObj));
} //发送消息通知后台代码
function notify(msg) {
window.external.Notify(msg);
}
</script>
</body>
</html>

default.html

  5)调用

    //拷贝安装目录文件到本地
await StorageHelper.Instance.CopyPackageFileToLocalAsync("Assets/Html/default.html", null, true);
Browser.Navigate(new Uri("Assets/Html/default.html", UriKind.Relative));

  

3、C#调用JS方法

  1、使用eval方法执行自定义代码

  2、使用x-wmapp0:引用本地路径

  3、使用 json2 进行json序列化

注意:后台代码调用JS的时候一般在 LoadCompleted 事件中调用

下面代码调用的方法见示例文件:default.html

    //1、获得HTML代码(两种方式)
var html = Browser.SaveToString();
var html = Browser.InvokeScript("eval", new[] {"document.documentElement.outerHTML;"}); //2、调用js方法(不带参数)
Browser.InvokeScript("InvokeFromCode"); //3、调用js方法(带参数,返回值)
var res = Browser.InvokeScript("InvokeFromCodeWithParam", new[] { "从后台代码调用js修改html" }); //4、动态加载js库(x-wmapp0:表示本地路径)
var js = @" var myScript = document.createElement(""script"");
myScript.type = ""text/javascript"";
myScript.src = ""x-wmapp0:Scripts/json2.min.js"";
document.body.appendChild(myScript);";
Browser.InvokeScript("eval", js); //5、调用js执行自定义代码(为图片添加点击事件,并通知)
js = @"
var imgs = document.getElementsByTagName(""img"");
for (var i = 0, len = imgs.length; i < len; i++) {
imgs[i].onclick = function (e) {
var jsonObj = { type: 'image', content1: this.src };
window.external.Notify(JSON.stringify(jsonObj));
};
}";
Browser.InvokeScript("eval", js);

4、Browser导航

    //刷新
Browser.InvokeScript("eval", "history.go()"); //后退(下面两种方式)
Browser.InvokeScript("eval", "history.go(-1)");
Browser.GoBack(); //前进(下面两种方式)
Browser.InvokeScript("eval", "history.go(1)");
Browser.GoForward();

5、缓存

  WebBrowser只提供了清除缓存和Cookie的方法,没有找到设置缓存的相关方法

    Browser.ClearCookiesAsync();
Browser.ClearInternetCacheAsync();

6、常见问题

2014年10月8日更新:

  使用WebBrowser.NavigateToString(string html)要注意,在WP8.0上,这里的html字符串中不要包括HTML文件的头部文档类型声明,否则会出现无法解析的问题

<!DOCTYPE html>

  我们把 <!DOCTYPE html> 删除之后,则可以正常渲染,这个问题在WP8.0的时候才会,在WP8.1之后不会

最后:

  动态资源的加载可以用于我们不能控制html内容的页面,比如我们访问百度页面,里面有很多图片,我们需要点击图片的时候,可以弹出框显示一张大图,同时可以让用户保存,这个时候我们可以动态加载JS,去监听所有的点击事件,这样,所有的页面的图片我们都能监听到点击事件了,而且能获取到图片链接

个人能力有限,如果上文有误或者您有更好的实现,可以给我留言

转载请注明出处:http://www.cnblogs.com/bomo/p/3949994.html

【WP8】WebBrowser相关的更多相关文章

  1. 记WinForm中WebBrowser相关的俩个问题

    问题一:如何不让WebBrowser中弹出“安全警告” 当链接https网址时,IE会自动弹出上图中的窗口. 关闭窗口的具体思路如下: 使用WebBrowser加载中/加载完毕后触发的事件处理程序,在 ...

  2. 【WP8.1】WebView笔记

    之前在WP8的时候做过WebBrowser相关的笔记,在WP8.1的WebView和WebBrowser有些不一样,在这里做一些笔记 下面分为几个部分 1.禁止缩放 2.JS通知后台C#代码(noti ...

  3. [Cocos2d-x For WP8]Hello world

    [Cocos2d-x For WP8]Hello world Cocos2d-x For WP8使用C++开发,使用cocos2d-xv0.13同样的接口,Cocos2d-x For WP8的相关项目 ...

  4. C# WinForm开发系列 - WebBrowser

    原文:C# WinForm开发系列 - WebBrowser 介绍Vs 2005中带的WebBrowser控件使用以及一些疑难问题的解决方法, 如如何正确显示中文, 屏蔽右键菜单, 设置代理等; 收集 ...

  5. unity的坑

    http://dearymz.blog.163.com/blog/static/20565742013341916919/ 编辑器: Hierarchy窗口中是场景中的Game Object列表 Pr ...

  6. GLView基本分析

    GLView是cocos2d-x基于OpenGL ES的调用封装UI库. OpenGL本身是跨平台的计算机图形实现API,在每一个平台的详细实现是不一样.所以每次使用之前先要初始化,去设置平台相关的信 ...

  7. 【Win10】实现 ListViewBase 平滑滚动

    首先解释下标题的 ListViewBase 是什么鬼.ListViewBase 我们可以查阅 MSDN 文档:https://msdn.microsoft.com/zh-cn/library/wind ...

  8. Effective C++ —— 设计与声明(四)

    条款18 : 让接口容易被正确使用,不易被误用 欲开发一个“容易被正确使用,不容易被误用”的接口,首先必须考虑客户可能做出什么样的错误操作.  1. 明智而审慎地导入新类型对预防“接口被误用”有神奇疗 ...

  9. WebBrowse使用

     C# WinForm开发系列 - WebBrowser 2009-12-14 14:19:21 标签:C# - WebBrowser 休闲 WinForm开发系列 介绍Vs 2005中带的WebBr ...

随机推荐

  1. DevOps是云计算时代的开发与运营

    DevOps(英文Development和Operations的组合)是一组过程.方法与系统的统称,用于促进开发(应用程序/软件工程).技术运营和质量保障(QA)部门之间的沟通.协作与整合.[1] 它 ...

  2. 移动端手势库hammerJS 2.0.4官方文档翻译

    hammerJS是一个优秀的.轻量级的触屏设备手势库,现在已经更新到2.04版本,跟1.0版本有点天壤地别了,毕竟改写了事件名并新增了许多方法,允许同时监听多个手势.自定义识别器,也可以识别滑动方向. ...

  3. 你写的Try...Catch真的有必要么?

    很多人喜欢用Try...Catch把每一个方法都包裹起来,可是真的有必要么? 为什么要这样做?我估计是大家被BUG吓怕了,生怕生产环境出现各种莫名其妙的错误,比如最经典的NullReferenceEx ...

  4. (源码下载)高灵活度,高适用性,高性能,轻量级的 ORM 实现

    我在上一篇博客中简单说明了一个面向内存数据集的“ORM”的实现方法,也提到我的设计实现或许不能称之为“ORM”,姑且称之为 S-ORM吧. 可能有些小伙伴没有理解我的思路和目的,与传统ORM框架做了简 ...

  5. MySQL 主主复制

    200 ? "200px" : this.width)!important;} --> 介绍 环境 OS:CentOS 6.7,MySQL 5.6 Master:192.16 ...

  6. [SDK2.2]Windows Azure Storage (15) 使用WCF服务,将本地图片上传至Azure Storage (上) 服务器端代码

    <Windows Azure Platform 系列文章目录> 这几天工作上的内容,把项目文件和源代码拿出来给大家分享下. 源代码下载:Part1 Part2 Part3 我们在写WEB服 ...

  7. Objective-C 工厂模式(下) -- 抽象工厂模式

    相比简单工厂模式, 只有一个工厂 能生产的手机也是固定的 抽象工厂模式类似于有很多家工厂, 当用户要买什么手机就创建对应的工厂去生产 比如用户要买iPhone就创建一个Apple工厂来生产手机, 要买 ...

  8. JSP的基本语法

    JSP的基本语法 一.JSP页面中的JAVA代码 二.JSP页面中的指令 三.JSP页面中的隐含对象(九大内置对象) 目录 一.JSP页面中的JAVA代码 JSP表达式(方便输出) JSP小脚本(完成 ...

  9. 将数据从MySQL迁移到Oracle的注意事项

    将数据从MySQL迁移到Oracle的注意事项1.自动增长的数据类型处理MYSQL有自动增长的数据类型,插入记录时不用操作此字段,会自动获得数据值.ORACLE没有自动增长的数据类型,需要建立一个自动 ...

  10. IM消息送达保证机制实现(二):保证离线消息的可靠投递

    1.前言 本文的上篇<IM消息送达保证机制实现(一):保证在线实时消息的可靠投递>中,我们讨论了在线实时消息的投递可以通过应用层的确认.发送方的超时重传.接收方的去重等手段来保证业务层面消 ...