WebBrowser

      在〈WebBrowser〉中尚無留言

使用WebBrowser的好處

C# 裏的WebBrowser常被用來顯示網頁的內容, 等於是在應用程式中崁入自己的瀏覽器

如果需要在應用程式中顯示資料庫裏的內容, 又要顯示圖片, 又要能複製內容到Excel, Word, 又要能提供搜尋的功能, 然後又要能將內容印出來. 回想一下, C#有那個元件能作到這些事呢?

沒錯, 上述的這些事都必需手動撰寫, 但工程何其浩大.  那倒不如直接使用WebBrowser當成flowDocument, 甚至當成DataGrid來使用

唯一的缺點是~~需要懂Html的語法

相關代碼

xaml如下

<Grid>
    <WebBrowser x:Name="web" />
</Grid>

相關程式碼如下

 private void btnSearch_Click(object sender, RoutedEventArgs e)
 {
     string html= html = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></head><body><table cellspacing='0' cellpadding='0'";
     string str = String.Format("select * from RoadData where 地區='{0}' and 日期 ='{1}' and 是否列印 ='是'", cmbArea.Text,pickerDate.Text);
     SqlCommand cmd = new SqlCommand(str, G.conn2);
     SqlDataReader dr = cmd.ExecuteReader();
     data = new ObservableCollection<Db2巡查日誌Item>();
     int index = 0;
     while (dr.Read())
     {
         string yyyy = Convert.ToDateTime(dr["日期"]).ToString("yyyy");
         int year = int.Parse(yyyy) - 1911;
         string MM = Convert.ToDateTime(dr["日期"]).ToString("MM");
         string dd = Convert.ToDateTime(dr["日期"]).ToString("dd");

         string urlImagePath = String.Format("http://ip/TP104/photo/{0}/{1}{2}{3}/{4}_far.png", cmbArea.Text, int.Parse(yyyy) - 1911, MM, dd, dr["缺失路段"]);
         string d1 = dr["主要分類"].ToString();
         string d2 = dr["次要分類"].ToString();
         string d3 = dr["損壞壤別"].ToString().Split('-')[1];

         if (index % 4 == 0) html += "<tr>";
         html += "<td>";
         html += "<table border='1' cellspacing='0' cellpadding='0'><tr>";
         html += "<td width='15'><font size='1'>序號</font></td>";
         html += string.Format("<td width='20'><font size='1'>{0}</td>", index + 1);
         html += "<td width='15'><font size='1'>地點</font></td>";
         html += string.Format("<td width='180'><font size='1'>{0}</font></td>", dr["缺失路段"]);
         html += "<td width='15'><font size='1'>損壞類別</font></td>";
         html += string.Format("<td width='120'><font size='1'>{0}<br>{1}<br>{2}</font></td>", d1, d2, d3);
         html += "</tr>";
         html += string.Format("<tr><td colspan='6' align='center'><img src='{0}' width=320 height=240/></td></tr>", urlImagePath);
         html += "</table>";
         html += "</td>";
         if (index % 4 == 3) html += "</tr>";
         index++;
    }
    html += "</table></body></html>";
    web.NavigateToString(html);
 }

上述紅色部份, 即是將html寫入webBrowser

結果如下

說真格的, 在應用程式中崁入WebBrowser, end user一點也感覺不到那裏不妥, 完全沒有違和感, 超讚的

web_1

取得WebBrowser控制項

WebBrowser是真的好用. 但如果裏面有按鈕, 那希望按鈕按了, 處理不同的事項時, 該如何取得按鈕被按下的事件呢!

底下的程式碼, 撰寫了一個script, 當按扭按下後, 會調用JavaScript的info()函數. info()則會調用sendMessage()這個方法.

但請注意, sendMesage()這個函數並不是javaScrit的函數. sendMessage是由C#經web.ObjectForScripting將ScriptHelper物件送進JavaScript的,然後由JavaScript的window.exteral去接收調用sh的sendMessage()方法.

致於 sendMessage()要作啥呢, 此時使用C#的 delegate指派Action ProcMessage 要處理的方法即可

web_script

using System;
using System.Runtime.InteropServices;
using System.Windows;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        [ComVisible(true)]
        public class ScriptHelper
        {
            public Action<string> ProcMessage = null;
            public void sendMessage(string msg)
            {
                if (ProcMessage != null)
                    ProcMessage(msg);
            }
        }
        public MainWindow()
        {
            InitializeComponent();
            string html = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></head><body>";
            html += "<table cellspacing='0' cellpadding='0' border='1' width='100%'>";
            html += "<tr><td>第一格</td><td>第二格</td><td>第三格</td>";
            html += "<td><button type = 'button' onclick='info(\"第一列\")'>按鈕1</button></td></tr>";
            html += "<tr><td>第一格</td><td>第二格</td><td>第三格</td>";
            html += "<td><button type = 'button' onclick='info(\"第二列\")'>按鈕2</button></td></tr>";
            html += "<tr><td>第一格</td><td>第二格</td><td>第三格</td>";
            html += "<td><button type = 'button' onclick='info(\"第三列\")'>按鈕3</button></td></tr>";
            html += "<tr><td>第一格</td><td>第二格</td><td>第三格</td>";
            html += "<td><button type = 'button' onclick='info(\"第四列\")'>按鈕4</button></td></tr>";
            html += "<tr><td>第一格</td><td>第二格</td><td>第三格</td>";
            html += "<td><button type = 'button' onclick='info(\"第五列\")'>按鈕5</button></td></tr>";
            html += "</table>"; 
            html += 
            @"<script language='JavaScript'>
                function info(str){
                    window.external.sendMessage(str);
                }
            </script>";            
            web.NavigateToString(html);
            ScriptHelper sh = new ScriptHelper();
            sh.ProcMessage = (s) =>ProcessScript(s);
            web.ObjectForScripting = sh;
        }
        private void ProcessScript(string s)
        {
            MessageBox.Show(s);
        }
    }
}

結果如下

webbrowser

列印WebBrowser

加入參考

列印 WebBrowser內容, 需加入 Microsoft.mshtml 參考, 請選擇擴充功能/Microsoft.mshtml, 如下圖

webbrowser_print

列印啟動代碼

如下代碼, sb是要傳給WebBrwoser的內容, 所以先判斷sb是否為空值, 若為空值表示WebBrowser還沒有資料, 不能列印

 if (sb != null)
 {
     mshtml.IHTMLDocument2 doc = web.Document as mshtml.IHTMLDocument2;
     doc.execCommand("Print", true, null);
 }

取得節點及更改屬性

mshtml.HTMLDocument document = (mshtml.HTMLDocument)web.Document;
mshtml.IHTMLElement img = document.getElementById("imgFar");
img.setAttribute("src", "data:image/jpg;base64," + bmp);

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *