在WPF中嵌入WebBrowser視覺化頁面

ZaraNet發表於2019-07-31

  無論是哪種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"));
        }

  就這樣~我們測試一下~

 

 

相關文章