無論是哪種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")); }
就這樣~我們測試一下~