在WPF中嵌入WebBrowser可視化頁面

  • 2019 年 10 月 3 日
  • 筆記

  無論是哪種C/S技術,涉及數據可視化就非常的累贅了,當然大神也一定有,只不過面向大多數人,還是通過網頁來實現,有的時候不想把這兩個功能分開,一般會是客戶的原因,所以我們打算在WPF中嵌入WebBrowser,然後使用ECharts 完成複雜的圖表展示,其功能不亞於一個名為Devexpress的圖標庫,而且這東西還收費(呵呵),本文就對WebBrowser+ECharts進行了演示。

  首先下載一下Echats.js文件以及Jquery文件並且創建一個Html頁面,在我們項目的bin文件夾中。

在html中編輯,其中包括了幾個方法,是對C#程式碼進行訪問的。

<!DOCTYPE html>  <html lang="zh-cn" xmlns="http://www.w3.org/1999/xhtml">  <!-- saved from url=(0013)about:internet -->  <head>      <meta charset="utf-8" http-equiv="X-UA-Compatible" content="IE=5,6,7,8,9,10,11, chrome=1" />      <title>ECharts</title>  </head>  <body>      <h1>html頁面</h1>      <button Onclick="click1()" style="width:100px;height:20px">測試</button>      <script>          function click1()          {              window.external.ShowMsg("這是一條資訊");          }      </script>      <div id="main" style="width:1000px;height:500px;margin-left:-8px" />      <script src="echats.js"></script>      <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>      <script>          myChart = echarts.init(document.getElementById('main'));          option = {              xAxis: {                  type: 'category',                  data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']              },              yAxis: {                  type: 'value'              },              series: [{                  data: [820, 932, 901, 934, 1290, 1330, 1320],                  type: 'line'              }]          };          myChart.setOption(option);      </script>      <script>          function SetOption(value) {              var dataObj = JSON.parse(value);//將字元串轉換為json對象              myChart.setOption(JSON.parse(dataObj));//將json對象轉換為[Object]          }          function jsShowHide(info) {              if (info == 0) {                  myChart.clear();              }              else {                  myChart.setOption(option);              }          }          function jsPushData(x, y) {              option.xAxis.data.push(x);              option.series[0].data.push(y);              myChart.setOption(option);          }      </script>  </body>  </html>

   現在我們需要編輯一下我們的WPF窗體,在其中放入我們的瀏覽器,然後讓它顯示我們剛剛寫好的頁面。

<Window x:Class="EachartsDemo.MainWindow"          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"          xmlns:d="http://schemas.microsoft.com/expression/blend/2008"          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"          xmlns:local="clr-namespace:EachartsDemo"          mc:Ignorable="d"          Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">      <Grid>          <Grid.RowDefinitions>              <RowDefinition Height="50"></RowDefinition>              <RowDefinition></RowDefinition>              <RowDefinition Height="100"></RowDefinition>          </Grid.RowDefinitions>          <TextBlock Grid.Row="0" Text="webBrowser" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="25"></TextBlock>          <WebBrowser Grid.Row="1" Name="Web"></WebBrowser>          <StackPanel Grid.Row="2" Orientation="Horizontal" VerticalAlignment="Center">              <TextBlock Text="wpf按鈕: " FontSize="20"></TextBlock>              <Button Grid.Row="2" Name="btnShowHide" Content="載入"  Click="btnShowHide_Click"></Button>              <Button Grid.Row="2" Name="btnAddSeries" Content="追加" Margin="10,0,0,0" Click="btnPushData_Click"></Button>              <Button Grid.Row="2" Name="btnSet" Content="重置" Margin="10,0,0,0" Click="SetOption">              </Button>          </StackPanel>      </Grid>  </Window>

  在Windows標記中我們需要一個Load事件用於讓WebBrowser跳轉到相應的頁面。

private void Window_Loaded(object sender, RoutedEventArgs e)          {              Web.Navigate(new Uri(Directory.GetCurrentDirectory() + "/Demo.html"));          }

  最後我們還需要創建幾個方法,用於讓C#直接調用其中Js方法。

int show = 0;          private void btnShowHide_Click(object sender, RoutedEventArgs e)          {              Web.InvokeScript("jsShowHide", show);              if (show == 0) show = 1;              else show = 0;          }            private void btnPushData_Click(object sender, RoutedEventArgs e)          {              Web.InvokeScript("jsPushData", "x", 1000,"y","200");          }            private void SetOption(object sender, RoutedEventArgs e)          {              string strobj = @"{""xAxis"":{""type"":""category"",""data"":[""Mon"",""Tue"",""Wed"",""Thu"",""Fri"",""Sat"",""Sun""]},""yAxis"":{""type"":""value""},""series"":[{""data"":[100,200,300,400,500,600,700],""type"":""line""}]}";              var aa = JsonConvert.SerializeObject(strobj.Trim());                  Web.InvokeScript("SetOption",aa);          }

  因為我們在xaml中把WebBrowser的name改成了Web,其中這個控制項自帶一個InvokeScript方法,就是來使用頁面寫好的Function,就這樣啟動~

   可見效果還可以,就現在我們要通過Js調用C#方法,首先編輯一個頁面可操作的類,我們創建 EchatsHelper ,必須在類上面標註特性,否則程式啟動不起來,因為WebBrowser是涉及一些安全性的東西,只要是在哪個類new出來,就必須在哪個類標註特性。

[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]      [System.Runtime.InteropServices.ComVisible(true)]//給予許可權並設置可見      public class EchatsHelper      {          WebBrowser web;          public EchatsHelper(WebBrowser web)          {              this.web = web;          }          public void ShowMsg(string Msg)          {              Console.WriteLine(Msg);          }      }

  最後我們在Load事件中創建應用程式對文檔文件的寄宿腳本訪問。

private void Window_Loaded(object sender, RoutedEventArgs e)          {              Web.ObjectForScripting = new EchatsHelper(Web);              Web.Navigate(new Uri(Directory.GetCurrentDirectory() + "/Demo.html"));          }

  就這樣~我們測試一下~

 

 

Tags: