重新想象 Windows 8.1 Store Apps (81) - 控件增强: 加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Contract 分享 WebView 中的内容, 为 WebView 截图

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 原文:重新想象 Windows 8.1 Store Apps (81) - 控件增强: 加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Contract 分享 WebView 中的内容, 为 WebView 截图[源码下载] 重新想象 Windows 8.
原文: 重新想象 Windows 8.1 Store Apps (81) - 控件增强: 加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Contract 分享 WebView 中的内容, 为 WebView 截图

[源码下载]


重新想象 Windows 8.1 Store Apps (81) - 控件增强: 加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Contract 分享 WebView 中的内容, 为 WebView 截图



作者:webabcd


介绍
重新想象 Windows 8.1 Store Apps 之控件增强

  • WebView 加载本地 html,智能替换 html 中的 url 引用
  • WebView 通过 Share Contract 分享
  • WebView 截图



示例
1、演示如何通过 WebView 加载本地 html, 以及智能替换 html 中的 url 引用
WebView/Local.xaml

<Page
    x:Class="Windows81.Controls.WebView.Local"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows81.Controls.WebView"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0">

            <Button Name="btnHtml" Content="解析指定的 html 字符串" Click="btnHtml_Click" />
            <Button Name="btnPackageHtml" Content="解析 package 中的 html" Margin="0 10 0 0" Click="btnPackageHtml_Click" />
            <Button Name="btnAppDataHtml" Content="解析 appData 中的 html" Margin="0 10 0 0" Click="btnAppDataHtml_Click" />

            <Button Name="btnSmart" Content="智能替换 html 中的 url 引用" Margin="0 10 0 0" Click="btnSmart_Click" />

            <WebView Name="webView" Width="800" Height="300" HorizontalAlignment="Left" Margin="0 10 0 0" />

        </StackPanel>
    </Grid>
    
</Page>

WebView/Local.xaml.cs

/*
 * 本例演示如何通过 WebView 加载指定的 html 字符串,加载 package 中的 html,加载 appData 中的 html
 * 还会演示如何以内容流的方式加载 html 数据,其有如下作用:
 * 1、可以实现完全从本地加载全部页面数据(包括 html,js,css,图片等)
 * 2、可以实现智能替换 html 中的 url 引用
 * 
 * WebView - 内嵌浏览器
 *     
 * 
 * 提示:
 * 在 win8 中 WebView 会挡住所有元素(包括 AppBar),而在 win8.1 中不会再有这种情况了
 * 如果想看看 win8 中全屏 WebView 如何不挡 AppBar,以及如何使用 WebViewBrush 以达到不遮挡其他元素的目的,请参看:http://www.cnblogs.com/webabcd/archive/2013/03/04/2942242.html
 * 
 * 注:win8 和 win8.1 中的 WebView 有很多区别,在 win8.1 中使用 WebView 请参考本系列教程,在 win8 中使用 WebView 请看考:http://www.cnblogs.com/webabcd/archive/2013/03/04/2942242.html
 */

using System;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.Web;
using Windows.Web.Http;

namespace Windows81.Controls.WebView
{
    public sealed partial class Local : Page
    {
        public Local()
        {
            this.InitializeComponent();
        }

        private void btnHtml_Click(object sender, RoutedEventArgs e)
        {
            // 解析指定的 html 字符串
            webView.NavigateToString("<html><body>I am webabcd</body></html>");
        }

        private void btnPackageHtml_Click(object sender, RoutedEventArgs e)
        {
            // 解析 package 中的 html
            string url = "ms-appx-web:///Controls/WebView/HtmlDemo.html";
            webView.Navigate(new Uri(url));
        }

        private async void btnAppDataHtml_Click(object sender, RoutedEventArgs e)
        {
            // 将程序包内的 html 文件复制到 ApplicationData 中的 LocalFolder
            StorageFolder localFolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("webabcdTest", CreationCollisionOption.OpenIfExists);
            StorageFile htmlFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Controls/WebView/HtmlDemo.html"));
            await htmlFile.CopyAsync(localFolder, "HtmlDemo.html", NameCollisionOption.ReplaceExisting);

            // 解析 appData 中的 html
            string url = "ms-appdata:///local/webabcdTest/HtmlDemo.html";
            webView.Navigate(new Uri(url));
        }


        // 以内容流的方式加载 html 数据
        // 智能替换 html 中的 url 引用
        // 在本例中,html 页面来自本地,html 中的引用来自远程
        private void btnSmart_Click(object sender, RoutedEventArgs e)
        {
            // 构造可传递给 NavigateToLocalStreamUri() 的 URI
            Uri url = webView.BuildLocalStreamUri("contentIdentifier", "/Controls/WebView/HtmlDemo.html");
            // 实例化一个实现 IUriToStreamResolver 接口的类
            StreamUriWinRTResolver myResolver = new StreamUriWinRTResolver();

            // 所有 url(包括 html 的 url 以及 html 内所有引用的 url)都会通过 StreamUriWinRTResolver 来返回数据流
            webView.NavigateToLocalStreamUri(url, myResolver);
        }
    }

    // 实现 IUriToStreamResolver 接口(用于将 url 以内容流的方式返回)
    public sealed class StreamUriWinRTResolver : IUriToStreamResolver
    {
        // IUriToStreamResolver 接口只有一个需要实现的方法
        // 根据 uri 返回对应的内容流
        public IAsyncOperation<IInputStream> UriToStreamAsync(Uri uri)
        {
            string path = uri.AbsolutePath;
            return GetContent(path).AsAsyncOperation();
        }

        // 根据 uri 返回对应的内容流
        private async Task<IInputStream> GetContent(string path)
        {
            string url;

            // 按需求修改 url 引用
            if (path == "/Controls/WebView/HtmlDemo.html")
                url = "ms-appx://" + path;
            else
                url = "http://ajax.googleapis.com" + path;

            if (url.StartsWith("http"))
            {
                // http 方式获取内容数据
                HttpResponseMessage response = await new HttpClient().GetAsync(new Uri(url), HttpCompletionOption.ResponseHeadersRead);
                return await response.Content.ReadAsInputStreamAsync();
            }
            else
            {
                // 获取本地数据
                StorageFile fileRead = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(new Uri(url, UriKind.Absolute));
                return await fileRead.OpenAsync(FileAccessMode.Read);
            }
        }
    }
}

本地 Html: 
WebView/HtmlDemo.html

<!--此 html 用于演示如何通过 WebView 加载本地 html,以及如何以内容流的方式加载 html 数据-->

<!doctype html>
<html>
<head>
    <title></title>
    <script type="text/javascript" src="/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
</head>
<body>
    <p>i am html2</p>
    <p id="lblMsg"></p>
    <script type="text/javascript">
        document.getElementById("lblMsg").innerHTML = window.jQuery;
    </script>
</body>
</html>


2、演示如何通过 Share Contract 分享 WebView 中的内容(复制到剪切板也是同理)
WebView/Share.xaml

<Page
    x:Class="Windows81.Controls.WebView.Share"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows81.Controls.WebView"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0">

            <Button Name="btnShare" Content="通过 Share Contract 分享 WebView 中的被选中的文本内容" Click="btnShare_Click" />

            <WebView Name="webView" Width="400" Height="300" Source="http://webabcd.cnblogs.com/" HorizontalAlignment="Left" Margin="0 10 0 0" />

        </StackPanel>
    </Grid>
</Page>

WebView/Share.xaml.cs

/*
 * 本例演示如何通过 Share Contract 分享 WebView 中的内容(复制到剪切板也是同理)
 * 
 * WebView - 内嵌浏览器
 *     CaptureSelectedContentToDataPackageAsync() - 获取 DataPackage 对象
 *     DataRequested - 共享操作开始时触发的事件(事件参数 DataRequestedEventArgs)
 * 
 * DataRequestedEventArgs - 共享操作开始时触发的事件
 *     GetDeferral() - 获取异步操作对象,同时开始异步操作,之后通过 Complete() 通知完成异步操作
 * 
 * 关于 DataPackage 等共享相关的知识点请参见:http://www.cnblogs.com/webabcd/archive/2013/07/04/3171085.html
 * 
 * 
 * 
 * 提示:
 * 在 win8 中 WebView 会挡住所有元素(包括 AppBar),而在 win8.1 中不会再有这种情况了
 * 如果想看看 win8 中全屏 WebView 如何不挡 AppBar,以及如何使用 WebViewBrush 以达到不遮挡其他元素的目的,请参看:http://www.cnblogs.com/webabcd/archive/2013/03/04/2942242.html
 *
 * 注:win8 和 win8.1 中的 WebView 有很多区别,在 win8.1 中使用 WebView 请参考本系列教程,在 win8 中使用 WebView 请看考:http://www.cnblogs.com/webabcd/archive/2013/03/04/2942242.html
 */

using System;
using Windows.ApplicationModel.DataTransfer;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Windows81.Controls.WebView
{
    public sealed partial class Share : Page
    {
        private DataTransferManager _dataTransferManager;

        public Share()
        {
            this.InitializeComponent();
        }

        private void btnShare_Click(object sender, RoutedEventArgs e)
        {
            _dataTransferManager = DataTransferManager.GetForCurrentView();
            _dataTransferManager.DataRequested += _dataTransferManager_DataRequested;

            DataTransferManager.ShowShareUI();
        }

        // 分享 WebView 中的被选中的文本内容
        async void _dataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
        {
            DataRequest request = args.Request;
            DataRequestDeferral deferral = args.Request.GetDeferral();

            DataPackage dataPackage = await webView.CaptureSelectedContentToDataPackageAsync();
            DataPackageView dataPackageView = dataPackage.GetView();

            // 如果用户选择了一段内容,则通过 WebView.CaptureSelectedContentToDataPackageAsync() 获取到的数据里就会有 StandardDataFormats.Text 格式的内容,此内容就是用户所选中的内容
            if (dataPackageView.Contains(StandardDataFormats.Text))
            {
                dataPackage.Properties.Title = "Title";
                dataPackage.Properties.Description = "Description";

                request.Data = dataPackage;
            }
            else
            {
                request.FailWithDisplayText("没有选中任何内容");
            }

            _dataTransferManager.DataRequested -= _dataTransferManager_DataRequested;

            deferral.Complete();
        }
    }
}


3、演示如何对 WebView 中的内容截图
WebView/Capture.xaml

<Page
    x:Class="Windows81.Controls.WebView.Capture"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows81.Controls.WebView"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0">

            <Button Name="btnCapture" Content="对此 WebView 中的当前内容截图" Click="btnCapture_Click" />

            <WebView Name="webView" Width="400" Height="300" Source="http://webabcd.cnblogs.com/" HorizontalAlignment="Left" Margin="0 10 0 0" />

            <StackPanel Margin="0 10 0 0" Orientation="Horizontal">
                <Image Name="imageOriginal" Width="400" Height="300" HorizontalAlignment="Left" />
                <Image Name="imageSmall" Width="400" Height="300" HorizontalAlignment="Left" Margin="10 0 0 0" />
            </StackPanel>

        </StackPanel>
    </Grid>
</Page>

WebView/Capture.xaml.cs

/*
 * 本例演示如何对 WebView 中的内容截图
 * 
 * WebView - 内嵌浏览器
 *     
 * 
 * 提示:
 * 在 win8 中 WebView 会挡住所有元素(包括 AppBar),而在 win8.1 中不会再有这种情况了
 * 如果想看看 win8 中全屏 WebView 如何不挡 AppBar,以及如何使用 WebViewBrush 以达到不遮挡其他元素的目的,请参看:http://www.cnblogs.com/webabcd/archive/2013/03/04/2942242.html
 * 
 * 注:win8 和 win8.1 中的 WebView 有很多区别,在 win8.1 中使用 WebView 请参考本系列教程,在 win8 中使用 WebView 请看考:http://www.cnblogs.com/webabcd/archive/2013/03/04/2942242.html
 */

using System;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Graphics.Imaging;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;

namespace Windows81.Controls.WebView
{
    public sealed partial class Capture : Page
    {
        public Capture()
        {
            this.InitializeComponent();
        }

        private async void btnCapture_Click(object sender, RoutedEventArgs e)
        {
            // 对 WebView 中的内容截图,并将原始图像数据放入内存流
            InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream();
            await webView.CapturePreviewToStreamAsync(ms);

            // 显示原始截图
            BitmapImage bitmapImage = new BitmapImage();
            bitmapImage.SetSource(ms);
            imageOriginal.Source = bitmapImage;



            // 定义缩略图的大小(最长边定义为 180)
            int longlength = 180, width = 0, height = 0;
            double srcwidth = webView.ActualWidth, srcheight = webView.ActualHeight;
            double factor = srcwidth / srcheight;
            if (factor < 1)
            {
                height = longlength;
                width = (int)(longlength * factor);
            }
            else
            {
                width = longlength;
                height = (int)(longlength / factor);
            }

            // 显示原始截图的缩略图
            BitmapSource small = await resize(width, height, ms);
            imageSmall.Source = small;
        }

        // 返回指定原图的缩略图数据
        private async Task<BitmapSource> resize(int width, int height, IRandomAccessStream source)
        {
            WriteableBitmap small = new WriteableBitmap(width, height);
            BitmapDecoder decoder = await BitmapDecoder.CreateAsync(source);
            BitmapTransform transform = new BitmapTransform();
            transform.ScaledHeight = (uint)height;
            transform.ScaledWidth = (uint)width;
            PixelDataProvider pixelData = await decoder.GetPixelDataAsync(
                BitmapPixelFormat.Bgra8,
                BitmapAlphaMode.Straight,
                transform,
                ExifOrientationMode.RespectExifOrientation,
                ColorManagementMode.DoNotColorManage);
            pixelData.DetachPixelData().CopyTo(small.PixelBuffer);

            return small;
        }
    }
}



OK
[源码下载]

目录
相关文章
|
7月前
|
测试技术 UED Python
App自动化测试:高级控件交互技巧
Appium 的 Actions 类支持在移动应用自动化测试中模拟用户手势,如滑动、长按等,增强交互性测试。ActionChains 是 Selenium 的概念,用于网页交互,而 Actions 专注于移动端。在Python中,通过ActionChains和W3C Actions可以定义手势路径,例如在手势解锁场景中,先点击设置,然后定义触点移动路径执行滑动解锁,最后验证解锁后的元素状态。此功能对于确保应用在复杂交互下的稳定性至关重要。
|
7月前
|
API 数据安全/隐私保护 iOS开发
利用uni-app 开发的iOS app 发布到App Store全流程
利用uni-app 开发的iOS app 发布到App Store全流程
228 3
|
7月前
|
iOS开发 开发者
一键制作 iOS 上架 App Store 描述文件教程
一键制作 iOS 上架 App Store 描述文件教程
|
7月前
|
iOS开发 UED
解决提交到App Store时的ITMS-90478和ITMS-90062错误
解决提交到App Store时的ITMS-90478和ITMS-90062错误
86 0
|
7月前
|
iOS开发 开发者
苹果iOS App Store上架操作流程详解:从开发者账号到应用发布
很多开发者在开发完iOS APP、进行内测后,下一步就面临上架App Store,不过也有很多同学对APP上架App Store的流程不太了解,下面我们来说一下iOS APP上架App Store的具体流程,如有未涉及到的部分,大家可以及时咨询,共同探讨。
|
7月前
|
安全 开发工具 数据安全/隐私保护
如何将应用程序发布到 App Store
如何将应用程序发布到 App Store
|
7月前
|
安全 开发工具 数据安全/隐私保护
如何将应用程序发布到 App Store
如何将应用程序发布到 App Store
|
4月前
|
缓存 NoSQL Linux
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
131 1
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
|
3月前
|
移动开发 前端开发 JavaScript
使用html-to-image代替html2canvas,结合jspdf实现下载pdf(下载截图下载前端dom元素)
本文介绍了在前端项目中,当使用`html2canvas`遇到问题时,如何使用`html-to-image`库作为替代方案,结合`jspdf`实现将DOM元素生成为PDF文件并提供下载。文章首先讨论了`html2canvas`可能遇到的问题,并提供了该库的使用示例代码。随后,详细介绍了`html-to-image`库的安装和使用方法,展示了如何将DOM元素转换为Canvas,再利用`jspdf`生成PDF文件。最后,文章通过示例代码说明了整个转换和下载的过程,并展示了效果截图。
111 0
|
6月前
|
资源调度 Windows
Windows系统yarn : 无法加载文件
Windows系统yarn : 无法加载文件