在早期推廣宣傳推出Windows Phone 7的時候,我們做了大量的工作去幫助客戶建立早期的應用程式,移植他們的已經成熟的應用到WP7市場上來。我們提供指導和協助幫助他們設計開發出符合産品設計标準和遵循WP7應用程式認證規範的應用程式。
像開發出來的程式有很多比如Telegraph Media Group的Telegraph Fashion應用程式。他們在開發這個應用的過程中和在我們微軟技術研發中心的Martin Beeby和Dave Brown花了一些時間解決一個特定的一個問題:如何良好的顯示HTML内容?
在這個應用中資料主要是來自于包含特定格式的HTML代碼的RSS 提要。如果是開發Silverlight應用程式一般的做法是使用WebBrowser控件,并且使用NavigateToString()方法通過傳遞包含HTML代碼的字元串參數顯示該内容。
但WP7平台上使用這種方式去顯示的時候,開發團隊一開始就遇到了一些問題:
1. WebBrowser控件暫時不能改變其背景色。(預設是白色的背景,在加載中可能會更内容的背景顔色不搭調)。
2. Telegraph想在他們的應用中把WebBrowser控件縮小放大的功能屏蔽掉。
我們同時來看待這些問題。為了使WebBrowser更契合使用者選擇的主題,使WebBrowser能夠改變背景色這個需求是很合理的。在黑背景上的白色Browser是要避免的,反之亦然。當時在解決這個問題的過程中,該團隊使用一些檢測代碼去偵測目前的背景顔色。通過轉換成一個顔色16進制的值,然後在CSS中去處理目前頁面的背景顔色。
下面是上述方法的代碼—我認為或許可以重構成更簡單的代碼—但是上述方法的整個過程是這樣的:在WebBrowser加載過程中,我們先檢測目前的字型顔色和背景顔色應該用什麼然後設定它們的值最後傳遞字元串給WebBrowser控件。現在我們忽略腳本—我們來解決第二個問題。
private string FetchBackgroundColor()
{
return IsBackgroundBlack() ? "#000;" : "#fff";
}
private string FetchFontColor()
return IsBackgroundBlack() ? "#fff;" : "#000";
private static bool IsBackgroundBlack()
return FetchBackGroundColor() == "#FF000000";
private static string FetchBackGroundColor()
string color;
Color mc =
(Color)Application.Current.Resources["PhoneBackgroundColor"];
color = mc.ToString();
return color;
private void wb1_Loaded(object sender, RoutedEventArgs e)
string fontColor = FetchFontColor();
string backgroundColor = FetchBackgroundColor();
SetBackground();
var html = "<p>Lorem ipsum dolor sit amet, consectetur " +
"adipiscing elit. Mauris sit amet dignissim purus. " +
"Pellentesque habitant morbi tristique senectus et " +
"netus et malesuada fames ac turpis egestas. " +
"Curabitur ante mauris, tempor congue lobortis id, " +
"gravida nec mi. Sed laoreet neque eget lacus " +
"vestibulum vel euismod sapien elementum. Maecenas " +
"malesuada, orci id facilisis volutpat, dui dui " +
"cursus nulla, luctus congue magna ligula sed urna." +
"</p>" +
"<p>Suspendisse luctus rutrum quam non rutrum. " +
"Maecenas sed mauris id metus sodales lobortis eu sit " +
"amet nibh. Lorem ipsum dolor sit amet, consectetur " +
"adipiscing elit. Donec convallis vehicula lacinia. " +
"Duis blandit vestibulum tristique. Morbi tincidunt " +
"lacinia condimentum. Morbi quis ipsum lorem, mollis " +
"lobortis quam. Curabitur ac lectus justo, non " +
"placerat sapien. Integer non sem nec elit fermentum " +
"placerat. Vivamus id metus quam. Aliquam erat " +
"volutpat. Cras et mauris cursus lectus dignissim " +
"commodo varius nec ligula.</p>";
var htmlScript = "<script>function getDocHeight() { " +
"return document.getElementById('pageWrapper').offsetHeight;" +
"}" +
"function SendDataToPhoneApp() {" +
"window.external.Notify('' + getDocHeight());" +
"}</script>";
var htmlConcat = string.Format("<html><head>{0}</head>" +
"<body style=\"margin:0px;padding:0px;background-color:{3};\" " +
"onLoad=\"SendDataToPhoneApp()\">" +
"<div id=\"pageWrapper\" style=\"width:100%; color:{2}; " +
"background-color:{3}\">{1}</div></body></html>",
htmlScript,
html,
fontColor,
backgroundColor);
webBrowser1.NavigateToString(htmlConcat);
webBrowser1.IsScriptEnabled = true;
webBrowser1.ScriptNotify +=
new EventHandler<NotifyEventArgs>(wb1_ScriptNotify);
private void SetBackground()
webBrowser1.Background = new SolidColorBrush(mc);
}
對于第二個問題,最初的方法是設定WebBrowser的IsHitTestVisible為False。當然這樣做會引發另一個問題,那就是由于WebBrowser中被嵌入了一個ScrollViewer,設定IsHitTestVisible為False後Scrollviewer的滑動也會被相應的禁用。現在的挑戰是要把WebBrowser控件的高度設定為内容的高度。
當時為了解決這個問題考慮了兩種方案。第一種就是寫一個方法去測量字元串内容的長度,但是這個方案沒有被執行。那是因為在需求中資料内容中圖檔的高度也是須要被測量的。
另一種方案就把字元串資料傳遞給WebBrowser控件,然後通過運作JavaScript方法去測量内容的高度,回傳高度資訊給Silverlight。最後設定WebBrowser控件的高度。這就上面JavaScript代碼要做的處理。這個ScriptNotify handler中代碼大緻如下:
private void wb1_ScriptNotify(object sender, NotifyEventArgs e)
// The browser is zooming the text so we need to
// reduce the pixel size by the zoom level...
// Which is about 0.50
webBrowser1.Height = Convert.ToDouble(e.Value) * 0.50;
如果不是處理比較長的内容,這個方法是很管用的。但是當WebBrowser的高度設定為超過1800像素時,程式運作是會直接崩潰掉。最後證明,還有更簡單的方法能達到同樣的效果。
與設定WebBrowser的IsHitTestVisible不同的是,我們可以在HTML代碼中設定meta 标簽,這樣就可以禁用Browser的放大縮小功能。
<meta name="viewport" content="width=320" />
<meta name="viewport" content="user-scalable=no" />
or
?
1 <meta name="viewport" content="width=320,user-scalable=no" />
這裡的标簽把可視區域設定成320像素(避免水準方向的滑動)同時指定了使用者不能在可視區域去縮放可視内容。将這些标簽注入到HTML代碼中就實作了我們的需求。其實,是很簡單的。解決問題的過程就是這樣,一步一步,一點一滴,堅持不懈的去思考,問題都是得到比較好的解決的。
希望對你有幫助,歡迎大家讨論。
本文轉自 wws5201985 51CTO部落格,原文連結:http://blog.51cto.com/wws5201985/771639,如需轉載請自行聯系原作者