• 【WP开发】WebView控件应用要点


    WebView控件我就不多作详细的介绍,相信大家都懂的,就算你没用过,你看他的名字和长相都知道它的用途了。就是用来显示HTML内容的。

    在WP 8.1的Runtime App中,这个控件大致有以下几个功能:

    1、显示指定URL的网页;

    2、可以直接呈现动态组装的HTML内容(文本);

    3、执行HTML页中的脚本;

    4、将呈现的HTML内容捕捉为图像。

    咱们逐个试玩一下。

    导航到指定URL

    调用以下方法可以指定一个URL,然后WebView会导航到该页面,注意是web页,不是应用程序页。

    public void Navigate ( Uri source );

    当调用了该方法后,会依次发生以下事件,我直接从开发文档中摘录。

    WebView navigation events occur in the following order:

    1. NavigationStarting
    2. ContentLoading
    3. DOMContentLoaded
    4. NavigationCompleted

    本来,WebView有一个LoadCompleted事件,在8.0时候常用,不过,在以后的版本会删除该事件,因此我们最好别用了,改为NavigationCompleted事件,当HTML内容正在加载但未加载完成这一阶段就是ContentLoading事件所处的阶段。

    好,来看个例子,这个例子模拟了一个简单到无法简单的浏览器,旨在演示,我就不弄那么多“花拳绣腿”的功能了。

    先看界面(XAML)。

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="auto"/>
            </Grid.RowDefinitions>
            <Grid Grid.Row="0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition Width="auto"/>
                </Grid.ColumnDefinitions>
                <TextBox x:Name="txtUrl"/>
                <AppBarButton Grid.Column="1"  Icon="Forward" IsCompact="True" Margin="0,-2,0,0" Click="OnNavigateUrl"/>
            </Grid>
            
            <WebView Grid.Row="1" x:Name="webView" NavigationCompleted="OnNavCompleted" ContentLoading="OnContentLoading" />
            
            <Grid Grid.Row="2">
                <TextBlock x:Name="tbMsg"  Margin="2,3" Foreground="Yellow" FontSize="20"/>
                <ProgressBar IsIndeterminate="True" x:Name="progressbar" Visibility="Collapsed" Foreground="SkyBlue" VerticalAlignment="Center"/>
            </Grid>
        </Grid>


    UI的东西我不解释了,我估计大家不可能看不懂的,你要是看不懂,我也没办法,所以我顺便废话一句,凡是学习.net的朋友们,请你们必须重视WPF,不仅是因为它强大,更是因为它有许多子集,如Silverlight、WP、RT App等应用开发都需要它。

    首先看处理按钮的Click事件的代码,这代码中让WebView导航到指定的网页。

            private void OnNavigateUrl ( object sender, RoutedEventArgs e )
            {
                if (string.IsNullOrWhiteSpace(txtUrl.Text))
                {
                    return;
                }
                string u = txtUrl.Text.Trim();
                if (u.StartsWith("http://") == false)
                {
                    u = "http://" + u;
                }
                webView.Navigate(new Uri(u));
            }

    上面代码你只关注最后一行就行了,对,就是这么容易。
    还有WebView的几个事件,这里我只演示ContentLoading和NavigationCompleted事件,其他的事件一样,就是套代码罢了。

            private void OnNavCompleted ( WebView sender, WebViewNavigationCompletedEventArgs args )
            {
                if (args.IsSuccess)
                {
                    tbMsg.Text = "导航完成。";
                }
                else
                {
                    tbMsg.Text = args.WebErrorStatus.ToString();
                }
                this.progressbar.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
            }
    
            private void OnContentLoading ( WebView sender, WebViewContentLoadingEventArgs args )
            {
                progressbar.Visibility = Windows.UI.Xaml.Visibility.Visible;
                tbMsg.Text = "正在加载……";
            }


    就这样,一般来说不是很复杂的代码,我是不会一行一行地解释的。运行程序后,在文本框中输入URL,这里我用MSDN的地址,MSDN是啥,不要问我。看截图。

    直接呈现HTML

    这是在WebView中呈现HTML内容的另一种方法,就是不必要指定一个URL,可以动态组装一个HTML内容段,然后调用NavigateToString方法直接呈现,参数很简单,就是表示HTML的字符串。由于这个太好办了,我直接举例子,这样比吹牛更直观。

    UI中的XAML:

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            
            <Button Content="生成并显示HTML内容" Click="OnClick"/>
            
            <WebView Grid.Row="1" x:Name="wv"/>
        </Grid>


    下面代码动态生成一串HTML内容,然后在WebView上呈现。

            private void OnClick ( object sender, RoutedEventArgs e )
            {
                string html = "<table border="2">" +
                              "<tr><th>第1列</th><th>第2列</th></tr>" +
                              "<tr><td>A</td><td>B</td></tr>" +
                              "<tr><td>C</td><td>D</td></tr>" +
                              "</table>";
                wv.NavigateToString(html);
            }

    最终效果如下图:

    调用HTML中的脚本

    要调用HTML中的脚本,脚本代码应该用一个函数来封装,然后在CLR中调用时指定函数的名字。通过调用InvokeScriptAsync方法可以执行HTML文档中的脚本函数,通常是JS脚本。

    InvokeScriptAsync方法的第一个参数指要调用的脚本函数的名字,第二个参数指定要传递给脚本的参数列表,通常可以用string[]来处理,如果脚本函数没有参数,就传递一个空的string数组。脚本参数都是字符串。

    如果脚本函数有返回值,那么InvokeScriptAsync方法会将脚本的执行结果返回,返回的内容都是以字符串的形式表示。

    下面的例子,首先在WebView中呈现HTML内容,该HTML文档中含有两个函数。setValue用于设置span元素的内容,getValue返回span元素的内容。实例将通过调用脚本来将span元素显示的数字依次加上1/减去1。

    XAML如下:

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <StackPanel Orientation="Horizontal">
                <Button Content="增加值" Click="OnInCre"/>
                <Button Content="减少值" Click="OnDeCre"/>
            </StackPanel>
            <WebView x:Name="wv" Grid.Row="1"/>
        </Grid>

    下面代码生成HTML文档:

                string html = "<html><head><title></title>" +
                            "<script type="text/javascript">" +
                                " function setValue(v) { var span = document.getElementById("spval"); span.innerHTML = v;}" +
                            "function getValue() { var span = document.getElementById("spval"); return span.innerHTML; }" +
                            "</script>" +
                        "</head><body>当前值为:<span id="spval">0</span></body></html>";
                wv.NavigateToString(html);

    下面代码将实现加1操作:

            private async void OnInCre ( object sender, RoutedEventArgs e )
            {
                // 获取当前值
                string curVal = await wv.InvokeScriptAsync("getValue", new string[] { });
                int v = Convert.ToInt32(curVal);
                // 加上1
                v += 1;
                // 设置新值
                await wv.InvokeScriptAsync("setValue", new string[] { v.ToString() });
            }

    减去1的代码与上面相似,只是将+=改为-=,就不再列举了。
    请看结果:

    捕捉预览图

    这个功能有点意思,它可以将WebView中已呈现的内容捕捉 为图像,并存到一个流对象中。实现这个功能的方法名为CapturePreviewToStreamAsync,它是一个可以异步等待的方法,需要一个流对象作为参数,这个流可以是内存流,也可以是文件流。

    下面例子将MSDN主页上的部分内容捕捉为图像。

                using (Windows.Storage.Streams.InMemoryRandomAccessStream str=new Windows.Storage.Streams.InMemoryRandomAccessStream())
                {
                    // 开始捕捉
                    await wv.CapturePreviewToStreamAsync(str);
                    // 创建位图
                    Windows.UI.Xaml.Media.Imaging.BitmapImage bmp = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
                    bmp.SetSource(str);
                    // 显示图像
                    img.Source = bmp;
                }

    请看结果:

    要注意,CapturePreviewToStreamAsync方法只能捕捉你在WebView中能看到的那部分内容,滚动条后面的内容是不会被捕捉的。也就是说,这个捕捉功能只关心看得见那部分内容,不是捕捉整个网页的,可能是考虑到性能的问题吧。

    本文几个示例的源码下载:http://files.cnblogs.com/tcjiaan/WebView%E5%9B%9B%E4%B8%AA%E7%A4%BA%E4%BE%8B.zip

    好了,收工,开饭。

  • 相关阅读:
    log4net 开启内部调试
    负载均衡的基本算法
    MapReduce算法形式六:只有Map独自作战
    MapReduce算法形式五:TOP—N
    MapReduce算法形式四:mapjoin
    MapReduce算法形式三:cleanup
    MapReduce算法形式二:去重(HashSet)
    MapReduce算法形式二:去重(shuffle)
    MapReduce算法形式一:WordCount
    理解yarn平台,理解万岁,肤浅理解也万岁~
  • 原文地址:https://www.cnblogs.com/tcjiaan/p/4132962.html
Copyright © 2020-2023  润新知