【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

 

好了,收工,開飯。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM