業級信息化系統絕大部分采用BS架構實現,如門戶網站、OA系統、電商網站等,通過瀏覽器輸入Web網址即可訪問,對于使用者來說非常便捷,對于開發維護者來說也非常方便,程序維護只需更新服務器即可,使用者無感知。但是CS架構的WinForm客戶端程序仍然具有很實用的價值,如WPS、IT類的集成開發環境(數據庫、圖形處理軟件)、PC端的小工具。本地程序處理性能更優秀,但是頻繁更新帶來不友好的客戶端體驗。還有一種非常常見且實用的業務場景, Web網頁與WinForm程序互相集成應用。
在百度網盤的網頁中,點擊【下載】按鈕,首先會檢查本地是否已經啟動客戶端網盤。如果未啟動,則彈出提示信息告知用戶需要打開客戶端程序進行下載。這就是一個典型的Web網頁中啟動客戶端程序的場景。更形象的應用場景是,WinForn/WPF客戶端程序嵌入Web程序,Web程序的網頁中js調用WinForm/WPF窗體以及業務方法。后面會詳細的介紹。
WinForm程序中集成網頁的基本原理就是通過一個包含類似瀏覽器功能的控件,將Web網頁載入并解析渲染出來。下面主要介紹 WinForm 集成 Web 網頁的幾種實現方式。
談論集成的問題之前,先了解一下瀏覽器的內核。
瀏覽器最重要或者說核心的部分是“Rendering Engine”,可大概譯為“渲染引擎”,不過我們一般習慣將之稱為“瀏覽器內核”。負責對網頁語法的解釋(如標準通用標記語言下的一個應用HTML、JavaScript)并渲染(顯示)網頁。 所以,通常所謂的瀏覽器內核也就是瀏覽器所采用的渲染引擎,渲染引擎決定了瀏覽器如何顯示網頁的內容以及頁面的格式信息。不同的瀏覽器內核對網頁編寫語法的解釋也有不同,因此同一網頁在不同的內核的瀏覽器里的渲染(顯示)效果也可能不同,這也是網頁編寫者需要在不同內核的瀏覽器中測試網頁顯示效果的原因。
內核分類
內核被包含在全世界最高的使用率的操作系統中,即為Windows操作系統,所以我們又經常把它稱之為IE內核。
Trident內核的常見瀏覽器有:
其中部分瀏覽器的新版本是“雙核”甚至是“多核”,其中一個內核是Trident,然后再增加一個其他內核。國內的廠商一般把其他內核叫做“高速瀏覽模式”,而Trident則是“兼容瀏覽模式”,用戶可以來回切換。
Gecko內核常見的瀏覽器:Mozilla Firefox、Mozilla SeaMonkey、waterfox(Firefox的64位開源版)、Iceweasel、Epiphany(早期版本)、Flock(早期版本)、K-Meleon。
WebKit內核常見的瀏覽器:Chrome、傲游瀏覽器3、Apple Safari (Win/Mac/iPhone/iPad)、Symbian手機瀏覽器、Android 默認瀏覽器。
參考網站:https://liulanmi.com/labs/core.html
Blink是一個由Google和Opera Software開發的瀏覽器排版引擎,Google計劃將這個渲染引擎作為Chromium計劃的一部分,并且在2013年4月的時候公布了這一消息。這一渲染引擎是開源引擎WebKit中WebCore組件的一個分支,并且在Chrome(28及往后版本)、Opera(15及往后版本)和Yandex瀏覽器中使用。
瀏覽器內核檢測
https://ie.icoa.cn 可檢測 PC 或手機瀏覽器內核和操作系統類型,包括Google Chrome的WebKit、IE的Trident、ME的Edge、Firefox的Gecko/Servo,以及Windows/MacOS/Linux/iOS/Android等的判斷。
WinForm Browser 控件
微軟WinForm開發框架中老牌控件。
CefSharp是一種將功能齊全的符合標準的web瀏覽器嵌入C#或VB.NET應用程序的簡單方法。CefSharp擁有WinForms和WPF應用程序的瀏覽器控件,以及自動化項目的OffScreen版本。CefSharp基于Chromium Embedded Framework,這是Google Chrome的開源版本。
實際項目應用效果如下:
Miniblink是一個追求極致小巧的瀏覽器內核項目,全世界第三大流行的瀏覽器內核控件。其基于chromium最新版內核,去除了chromium所有多余的部件,只保留最基本的排版引擎blink。Miniblink保持了10M左右的極簡大小,是所有同類產品最小的體積,同時支持windows xp、npapi。
GeckoFX是skybound工作室開發的一個開源的用于方便將gecko引擎(最主要的瀏覽器是firefox)鏈接到.net 窗體應用的一個組件。它是用C#寫成的,里面有大量的C#的注釋,geckofx是最完美的默認的iE核心webbrowse控件的替代控件。
DotNetBrowser能嵌入一個基于Chromium的WPF或WinForms組件到你的.NET應用中,用來顯示使用HTML5、CSS3、JavaScript、Silverlight等技術構建的現代網頁。
Microsoft Edge WebView2 控件允許在本機應用中嵌入 web 技術(HTML、CSS 以及 JavaScript)。 WebView2 控件使用 Microsoft Edge(Chromium) 作為繪制引擎,以在本機應用中顯示 web 內容。 使用 WebView2,可以在本機應用的不同部分嵌入 Web 代碼,或在單個 WebView 實例中生成所有本機應用。
所以在客戶端程序中嵌入網頁程序,首選CefSharp。
歡迎關注、點贊、評論、轉發,每天都能獲取IT優質內容。
#人民網評錢楓被指性侵#
azor 同時支持 C# (C sharp) 和 VB (Visual Basic)。
主要的 Razor C# 語法規則
Razor 代碼塊包含在 @{ ... } 中
內聯表達式(變量和函數)以 @ 開頭
代碼語句用分號結束
變量使用 var 關鍵字聲明
字符串用引號括起來
C# 代碼區分大小寫
C# 文件的擴展名是 .cshtml
C# 實例
<!-- Single statement block -->
@{ var myMessage ="Hello World"; }
<!-- Inline expression or variable -->
<p>The value of myMessage is: @myMessage</p>
<!--Multi-statement block -->
@{
var greeting = "Welcome to our site!";
var weekDay = DateTime.Now.DayOfWeek;
var greetingMessage = greeting + " Here in Huston it is: " + weekDay;
}
<p>The greeting is: @greetingMessage</p>
運行實例 ?
主要的 Razor VB 語法規則
Razor 代碼塊包含在 @Code ... End Code 中
內聯表達式(變量和函數)以 @ 開頭
變量使用 Dim 關鍵字聲明
字符串用引號括起來
VB 代碼不區分大小寫
VB 文件的擴展名是 .vbhtml
實例
<!-- Single statement block -->
@Code dim myMessage = "Hello World" End Code
<!-- Inline expression or variable -->
<p>The value of myMessage is: @myMessage</p>
<!-- Multi-statement block -->
@Code
dim greeting = "Welcome to our site!"
dim weekDay = DateTime.Now.DayOfWeek
dim greetingMessage = greeting & " Here in Huston it is: " & weekDay
End Code
<p>The greeting is: @greetingMessage</p>
運行實例 ?
它是如何工作的?
Razor 是一種將服務器代碼嵌入在網頁中的簡單的編程語法。
Razor 語法是基于 ASP.NET 框架,專門用于創建 Web 應用程序的部分 Microsoft.NET 框架。
Razor 語法支持所有 ASP.NET 的功能,但是使用的是一種簡化語法,對初學者而言更容易學習,對專家而言更有效率的。
Razor 網頁可以被描述成帶以下兩種類型內容的 HTML 網頁: HTML 內容和 Razor 代碼。
當服務器讀取頁面時,它首先運行 Razor 代碼,然后再發送 HTML 頁面到瀏覽器。在服務器上執行的代碼能夠執行一些在瀏覽器上不能完成的任務,比如,訪問服務器數據庫。服務器代碼能創建動態的 HTML 內容,然后發送到瀏覽器。從瀏覽器上看,服務器代碼生成的 HTML 與靜態的 HTML 內容沒有什么不同。
帶 Razor 語法的 ASP.NET 網頁有特殊的文件擴展名 cshtml(Razor C#)或者 vbhtml(Razor VB)。
使用對象
服務器編碼往往涉及到對象。
"Date" 對象是一個典型的內置的 ASP.NET 對象,但對象也可以是自定義的,一個網頁,一個文本框,一個文件,一個數據庫記錄,等等。
對象有用于執行的方法。一個數據庫記錄可能有一個 "Save" 方法,一個圖像對象可能有一個 "Rotate" 方法,一個電子郵件對象可能有一個 "Send" 方法,等等。
對象也有用于描述各自特點的屬性。一個數據庫記錄可能有 FirstName 和 LastName 屬性。
ASP.NET Date 對象有一個 Now 屬性(寫成 Date.Now),Now 屬性有一個 Day 屬性(寫成 Date.Now.Day)。下面實例演示了如何訪問 Data 對象的一些屬性:
實例
<table border="1">
<tr>
<th width="100px">Name</th>
<td width="100px">Value</td>
</tr>
<tr>
<td>Day</td><td>@DateTime.Now.Day</td>
</tr>
<tr>
<td>Hour</td><td>@DateTime.Now.Hour</td>
</tr>
<tr>
<td>Minute</td><td>@DateTime.Now.Minute</td>
</tr>
<tr>
<td>Second</td><td>@DateTime.Now.Second</td>
</tr>
</td>
</table>
運行實例 ?
If 和 Else條件
動態網頁的一個重要特點是,您可以根據條件決定做什么。
做到這一點的常用方法是使用 if ... else 語句:
實例
@{
var txt = "";
if(DateTime.Now.Hour > 12)
{txt = "Good Evening";}
else
{txt = "Good Morning";}
}
<html>
<body>
<p>The message is @txt</p>
</body>
</html>
、基本的css兼容:
1、可能很多人喜歡用css hack的形式去兼容ie瀏覽器,但是我自己用起來感覺其實不好使 。ie7-就不考慮了,問題在哪呢,就在ie8的甑別上,你怎么讓樣式只對ie8起作用。上網搜你可能會得到這樣的答案:
.selector { color: #ff0>.selector { color: #ff0\0;/*ie8*/ color: #f00\9\0;/*ie9+*/}<;/*ie8*/ color: #f00>.selector { color: #ff0\0;/*ie8*/ color: #f00\9\0;/*ie9+*/}<;/*ie9+*/}
但是實際上你一試就嗝屁了,因為ie8他就是識別ie9能識別的,所以根本不能讓獨立的樣式只對ie8起作用。
(這個hack是可以區分ie8和ie9的,之前由于未知原因導致瀏覽器測試不成功,重裝系統后發現是可用的,后來又在多臺機器上測試過,證明是正確的。很抱歉誤導了大家,特此修正,仍然建議用文檔注釋的方式去獨立寫hack,當然最好是可以優雅降級,避免使用css hack。)
更好用的是什么呢,是用ie瀏覽器獨有的文檔注釋的方式。像這樣:
<!DOCTYPE html><!--[if IE 8 ]> <html class="ie8" lang="en"> <![endif]--><!--[if IE 9 ]> <html class="ie9" lang="en"> <![endif]--><!--[if (gt IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
屢試不爽,關鍵是可以獨立的維護處理兼容ie瀏覽器的樣式表,又不會淹沒在一大堆css hack標識中,只需要在獨立對ie8應用樣式規則的地方,copy該條規則,然后在前面加上 .ie8然后就能隨便寫了,對付ie9也一樣。
2、對于360雙核這種找抽瀏覽器,據說添加以下頭部meta信息可以使得網頁用webkit內核渲染:
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
IE=edge:保持使用最高級別模式顯示內容;
chrome=1:谷歌的外掛插件Google Chrome Frame(谷歌內嵌瀏覽器框架GCF),使用IE瀏覽網頁時實際上是使用Chrome瀏覽器內核渲染,最低支持IE6,但前提是客戶端已經安裝GCF。
但實際上這個meta標識是ie瀏覽器所識別的(詳情:),并不是公認的標準,所以用雙核的瀏覽器會傲嬌。當然360也會傲嬌,所以有時你會發現360并不能總是(也可能是我本人rp差)以chrome內核渲染你的按現代標準開發的網頁。
那么試試這個吧,添加:<meta name="renderer" content="webkit">
這個meta標識是360自家實現的(詳情:),表示強制要求360這造福中國社會萬千網民的瀏覽器用chrome的內核渲染網頁。
ok,一行代碼搞定360絕大部分的兼容。
二、ie8的css兼容
現在說說ie8下的css問題:
1、ie8支持:first-child,但不支持:last-child。因為前者是css2.1標準,后者是css3標準。參下:
CSS 2.1 selectors:Basic CSS selectors including: * (universal selector), > (child selector), :first-child, :link, :visited, :active, :hover, :focus, :lang(), + (adjacent sibling selector), [attr], [attr="val"], [attr~="val"], [attr|="bar"], .foo (class selector), #foo (id selector)
2、 為什么會發現上面的奇怪的東西(怪我css2.1和css3分不清),因為編譯sass文件后發現ie8下的樣式基本全歇菜了。需要注意的是,如果瀏覽器 不支持的選擇器和支持的選擇器寫在一起,那么整條規則就不起作用了。比如你不小心創造了一個偽元素(是真的偽哦).bb:bb-child, .cc{background:#333;}那么這整條規則就不起作用了,所有瀏覽器在此情況下都會歇菜,.cc的樣式就丟失了。
3、 input設置了左右padding,but輸入較多內容時padding還是會消失。這個問題是無解的,ie瀏覽器她就是這么渲染input的,解決方法是在input 外面套一層div,用div設置左右padding,border,width和height,input只需要設置width和weight為100% 即可。另外,正常來講,如果沒有明確設置height的值,那么設置的line-height值就是height的值,but對于ie8,如果input 設置了 line-height,那么input必須設置height,否則input的內容顯示有問題,會上下隱藏部分內容,她就是要躲貓貓。
4、 為什么上面我不用input的偽元素進行設置而要嵌套多一層div呢?因為input,img,iframe等元素不支持偽元素 -_-||。:before 和:after偽元素指定了一個元素文檔樹內容之前和之后的內容。與'content'屬性聯用,指定了插入的內容(也就是你必須顯性設置content 屬性這兩個偽家伙才能在文檔中顯示出來,哪怕設置content屬性為空字符串也行)。作為DOM元素,偽元素都是在容器內進行渲染的, input,img,iframe等元素都不能包含其他元素,也就是不是容器,所以不能通過偽元素插入內容。
5、 table中如果不是嚴格的用于表格,而是用于奇葩的局部布局時(我也想問為什么用來布局。。),td設置成inline-block可以排成一行,但是 ie8和ie9 下,如果td中的內容很長,即使td設置了寬度,td也會撐開并占用td設置的margin(廢話,td是沒有margin可言的),直到擠占所有的td 寬度之和為tr的寬度。但是td設置成float:left;就能表現成block。這個不清楚為什么,但是管用。。
6、父元素的左padding會和子元素的左margin重疊。這個是沒有好好實現盒子模型的事情了,包容吧。。
7、sprite圖中的icons之間最好留空白間隔,哪怕間隔1px也好,否則ie8下會出現使用了某一個icon當背景,icon后面跟著的其他icon也順帶顯示了一小部分的bug,所以icons之間還是要適當留白,不要太省。
三、ie11部分css問題
1、ie11下很多元素表現和其他瀏覽器不一致,比如對應用了同一樣式(不設置 高度)的div,其他瀏覽器解析的高度是一致的,但是ie11下該div有可能高度偏大,由此導致一些排版上的問題,所以,如果發現元素排版上下偏移的問題,查看此元素或其當代元素是否設置了高度,統一添上高度一切都ok了。
2、抱歉,ie11問題確實不多。
四、結尾附上一個關于css優先級的奇談
首先我們知道:
1、id選擇器優先級權重比class選擇器大一個數量級,class選擇器權重比標簽選擇器大一個數量級;
2、class選擇器和屬性選擇器同優先級;
3、樣式的優先程度需要根據第1條規則計算整體的優先級,按選擇器權重計算各條樣式規則中所有選擇器優先級之和,哪條規則權重大,那條就說了算。如果相同那么后面的覆蓋前面的。4、像這種.dog > p開掛,多了特殊符號的,并不會增加優勢,還是和 .dog p優先級一樣。
然后可以拋出一個問題了:
對于下面的文檔結構,分別對 p | .p | div p | .parent | #parent設置color屬性,那么優先級如何呢?
<div id="parent" class="parent">
<p class="p">p</p>
</div>
結果很有意思:
也就是 .p > div p > p > #parent > .parentid選擇器居然比p選擇器優先級還低!將p元素和div元素分開看,.p > div p > p 很正常, #parent > .parent也很正常。所以問題關鍵在子級p和父級#parent, 子級的選擇器優先級比父級的選擇器優先級高,或者說繼承的優先級程度比自身的優先級低!嵌套多一層看看就知道是不是了,分別對#parent | div | p設置color屬性:<div id="parent" class="parent"> <div class="mid"> <p id="p" class="p">p</p> <div></div>結果確實是p > div > #parent:
即使應用兩個選擇器也無濟于事,依然是p >#parent div
但是只要能定位到p元素,那么父級選擇器的權重就起作用了,一試便知,對#parent p | #p 設置同樣的樣式結果是這樣的:
嗯,確實如此。所以:
5、css樣式優先級還和繼承有關,繼承的優先級不如本身應用的優先級高。
總結完畢,敬禮。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。