前言
最近在嘗試Silverlight上呈現HTML內容,花了不少時間,可以說沒有真正的好方案,以下是我的測試結果,供各位網友參考。
測試內容
我主要想測4個東西,
- 給HTML文字是否可以呈現,包含了Table。
- 給URL瀏覽其他網站,且可以完整的呈現。
- 可否Javascript操作。
- 能不能Print印列其內容。
WebBrowser
JS:可(同網域) HTML:可 Web:可 Print:可
本來很期待Silverlight 4這一個功能的,而且在教學影片或聽老師們介紹,我好像都沒有注意到它一定要在Out of Browser (OOB)才能執行,等到真正開始測的時候才發現,令人大失所望,而且我在測試時按右鍵,看到了IE的選項,我終於知道他為什麼要OOB了,因為要與COM整合,呼叫IE的核心,很想說Silverlight開發團隊也太懶了吧,不過又想想寫一個Browser也不是簡單的事,而印列方面必需搭配WebBrowserBrush,如下面的範例。
// 用WebBrowserBrush截取Web畫面
WebBrowserBrush brush = new WebBrowserBrush();
brush.SetSource(this.webBrowser1);
PrintDocument print = new PrintDocument();
print.PrintPage += (obj, args) =>
{
args.PageVisual = new Border() { Background = brush };
args.HasMorePages = false;
};
print.Print("Print Test");
相關教學
Silverlight 4 HTML Puzzle: How Does It Work? <--很贊的範例。
SILVERLIGHT 4'S NEW HTML HOSTING SUPPORT
什麼是Out of Browser? |
Out of Browser是可以讓Silverlight安裝在Window的電腦上執行,不需要使用瀏覽器就可以使用,相對的可以取得較多的功能與權限,如果想在Linux上也要用Out of Browser功能,網路上說MoonLight 3可以支援,不過我沒試過,而且像WebBrowser這種用COM的元件,真的可以在Linux上執行嗎?令人懷疑,而Mac上暫時沒有看到相關的技術,可以讓Silverlight Out of Browser。 |
RichTextBox
JS:否 HTML:否 Web:否 Print:可
RichTextBox測試只能使用XAML,除非學下面的幾個元件去將HTML轉成XAML(不是百分之百就是了),還有印列時只會對RichTextBox的外觀繪圖,如果文字太長有Scrollbor,Scrollbor也會印列,不過小弟有試出無分頁的解決方法。
/// <summary>
/// 用遞迴找出ScrollViewer
/// </summary>
private ScrollViewer GetScrollViewer(DependencyObject parent)
{
if (parent == null)
{
return null;
}
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
DependencyObject temp = VisualTreeHelper.GetChild(parent, i);
if (temp is ScrollViewer || ((temp = GetScrollViewer(temp)) is ScrollViewer))
{
return temp as ScrollViewer;
}
}
return null;
}
// 只要針對MS.Internal.RichTextBoxView輸入,就可以得到全面書面,但超出一張大小會被截掉。
UIElement target = GetScrollViewer(rtb).Content as UIElement;
args.PageVisual = target;
// 預覽也可以用MS.Internal.RichTextBoxView。
previewImage.Source = new WriteableBitmap(target, null);
暫時還沒有去研究如何讓PringDocuemnt分頁,如果有好方案可以告許我。
相關教學
Silverlight Text Editor Sample
RichTextBox RichTextArea 傻傻分不清楚 |
我找到很多Silverlight 4 Beta的範例(2010/3以前的),如果你是跟我一樣使用Silverlight 4 Tools RC2 for Visual Studio 2010開啟範例,你百分百之也無法執行,錯在找不到RichTextArea這個控制器,原來它改名成RichTextBox,連Method也改名了,請把SetPropertyValue改成ApplyPropertyValue。 |
HtmlHost 假貨系列
JS:可(同網域) HTML:可 Web:可 Print:否
為什麼叫假貨系列呢,因為他們的控制項不是真的在Silverlight中,而是在Silverlight上放一個Html的iframe,用Dom與javascript去互動,害我一開始看到Demo很開心,想說找到可行方案了,仔細操作才發現他們是假的,還有因為是使用DOM無法在Out of Browser上操作、Silverlight enableHtmlAccess 屬性必需設定為 true,PrintDocument也無法印列其內容 。
Html Host Control
這就是他們的實作方式。
divelements HtmlHost
跟上一個元件同樣的操作原理。
ComponentOne HtmlHost
雖然我覺得這作法很假,但WebBrowser好像也沒好到那裡去,而且還不用Out of Browser,我試過新增移除放大縮小,後二個都有寫DOM+Javascript去操作,只是有時差(試試ComponentOne HtmlHost Demo就可以感受了)。
Liquid RichTextBox
JS:否 HTML:免強可 Web:否 Print:可
這元件有提供HTML的匯入與匯出,匯出正常,但匯入是這元件用將HTML解悉成XAML,太複雜的格式會失敗,雖然無法使用Javsscript,但可以寫Silvelight的Code去互動,如範例。
// 當匯入從文字轉成Xaml元件時發生的事件
this.RichTextBox.ElementRead += (obj, args) =>
{
if (args.Source is Image)
{
// 當元件是圖片,點擊圖片時放大。
args.Source.MouseLeftButtonUp += (img, mouseArgs) =>
{
ChildWindow cw = new ChildWindow();
cw.Width = 800;
cw.Height = 600;
Image i = new Image();
i.Source = (img as Image).Source;
i.Stretch = Stretch.Uniform;
cw.Content = i;
cw.Show();
};
}
};
公司內的一個專案用了這個元件半年多了,在Silvelight 4還沒出來前,這是試過最好的RichTexBox,不過對中文支援度非常的差,有時跑動畫,RichTextBox內有中文字就死當了,為什麼動畫呢?,那個專案是Online Project Manager,每個Project下有WeeklyNote,而WeeklyNote就是使用這一個元件,不同的Project與WeeklyNote切換應好客戶的要求,要有過場動畫,還有打中文字有時文字會暫時消失,按下Enter才會重現等等只有輸入中文才會發生的問題,不然我覺得滿好用的。
HtmlTextBox
JS:否 HTML:免強可 Web:否 Print:可
這是早在Silverlight 2時國外的高手就寫出如何將HTML轉成XAML的元件,雖然能轉換的格式不多,如果是很簡單的需求,可以參考這個元件。
Template = XamlReader.Load(
"<ControlTemplate " +
"xmlns='http://schemas.microsoft.com/client/2007' " +
"xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>" +
"<TextBlock " +
"x:Name=\"TextBlock\" " +
"/>" +
"</ControlTemplate>") as ControlTemplate;
ApplyTemplate();
動態載入XAML成Template就是從這個元件學到的。