Silverlight RichTextBox 保存格式解決方案
在新聞、留言板等系統(tǒng)中一種常見的需求是,保存用戶的輸入到數(shù)據(jù)庫(kù),顯示時(shí)不能丟失格式。
轉(zhuǎn)載請(qǐng)注明出處:http://www.rzrgm.cn/brooks-dotnet/archive/2010/11/10/1874181.html
Silverlight 4 提供了一個(gè)RichTextBox控件,可以輸入一些富文本信息,如超鏈接、圖片等,并可以設(shè)置格式。RichTextBox提供了一個(gè)Xaml 屬性,獲取或設(shè)置 RichTextBox 中內(nèi)容的 XAML 表示形式。
Xaml 屬性返回的 XAML 字符串將只包括以下元素:(摘自MSDN)
雖然已經(jīng)包括了大部分的元素,但是缺少一個(gè)關(guān)鍵的元素:圖片。很多信息都是圖文并茂的,這樣用RichTextBox顯示圖片就有點(diǎn)困難了。且由于Silverlight是客戶端技術(shù),對(duì)訪問(wèn)本地資源有嚴(yán)格的安全性限制,Silverlight 4 只有在提升權(quán)限的情況下才可以訪問(wèn)系統(tǒng)剪切板中的部分元素。在Silverlight 4 中,只能粘貼剪切板中的文字信息,不能粘貼圖片,且內(nèi)容格式全部丟失。經(jīng)過(guò)多方查找資料、測(cè)試,我找到兩種解決方案。
一、第三方組件:SLaBv0.9
在這里查看作者的博客。RichTextBox還有一個(gè)屬性:Blocks。
Blocks 屬性是 RichTextBox 的內(nèi)容屬性。它是 Paragraph 元素的集合。每個(gè) Paragraph 元素中的內(nèi)容都可包含下列元素:
InlineUIContainer 可包含 UIElement,例如 Image 或 Button。
這個(gè)組件的作者實(shí)現(xiàn)了一個(gè)Xaml的序列化、反序列化類,能夠從Blocks中提取出圖片,在需要時(shí)顯示,可以參考他的源代碼。
我寫了一個(gè)簡(jiǎn)單的測(cè)試程序,在RichTextBox中輸入內(nèi)容后,點(diǎn)擊預(yù)覽按鈕查看:
將RichTextBox的Blocks作為屬性傳遞給預(yù)覽窗口:
this.PreviewWindow.Show();
在預(yù)覽窗口中進(jìn)行解析:
代碼{
UiXamlSerializer uxs = new UiXamlSerializer();
ObservableObjectCollection ooc = new ObservableObjectCollection();
foreach (Block b in this.blocks)
{
ooc.Add(b);
}
string xaml = uxs.Serialize(ooc);
ObservableObjectCollection bc = (ObservableObjectCollection)XamlReader.Load(xaml);
this.txt預(yù)覽.Blocks.Clear();
foreach (Block b in bc)
{
this.txt預(yù)覽.Blocks.Add(b);
}
}
最終運(yùn)行效果:
這種方案的好處是非常簡(jiǎn)潔,如果內(nèi)容不需要保存到數(shù)據(jù)庫(kù),只用來(lái)顯示,那將非常好。但是若需要保存到數(shù)據(jù)庫(kù),且不丟失格式,就很困難了。下面我們來(lái)看第二種解決方案,可以完美的解決這個(gè)問(wèn)題。
二、Telerik的商業(yè)組件
Telerik是一個(gè)專業(yè)的組件、控件公司,其官方主頁(yè)是:http://www.telerik.com/。
除了Silverlight,該公司還開發(fā)了WinForm、WPF、ASP.NET AJAX、ASP.NET MVC等很多組件,界面非常華麗,源碼是學(xué)習(xí)UI的好示例。
我使用的是目前的最新版本:RadControls for Silverlight version: 2010.2 924 (Sep 24, 2010),可以在這里下載試用版本(需要先注冊(cè)):
安裝完后會(huì)給VS2010添加一個(gè)插件,且工具箱中包含了其所有的控件:
下面是我的測(cè)試項(xiàng)目:
數(shù)據(jù)庫(kù)使用的SQLite,用ADO.NET For SQLite、WCF做的數(shù)據(jù)訪問(wèn)。
使用了RadRichTextBoxRibbonUI和RadRichTextBox兩個(gè)控件,保存、顯示圖片的關(guān)鍵代碼是:
代碼{
IDocumentFormatProvider provider = new XamlFormatProvider();
string exportValue = String.Empty;
using (MemoryStream output = new MemoryStream())
{
provider.Export(document, output);
output.Seek(0, SeekOrigin.Begin);
using (StreamReader reader = new StreamReader(output))
{
exportValue = reader.ReadToEnd();
}
}
return exportValue;
}
private RadDocument fnImportXaml(string content)
{
IDocumentFormatProvider provider = new XamlFormatProvider();
RadDocument document;
using (MemoryStream stream = new MemoryStream())
{
StreamWriter writer = new StreamWriter(stream);
writer.Write(content);
writer.Flush();
stream.Seek(0, SeekOrigin.Begin);
document = provider.Import(stream);
}
return document;
}
數(shù)據(jù)庫(kù)中存的是Telerik的Xaml:
可以看到圖片已經(jīng)編碼過(guò)了,所有的格式都會(huì)保存。
這種方案的優(yōu)點(diǎn)是可以保存完整的格式信息,包括圖片等。缺點(diǎn)是效率不高,當(dāng)圖片很多很大時(shí),存取將會(huì)很慢。
以上是我查找到的解決方案,若你有別的方法,歡迎分享。
注:這個(gè)項(xiàng)目是我給公司做的一個(gè)幫助中心,用來(lái)查看常見問(wèn)題的解決方法,有很多功能尚未完善。
項(xiàng)目很大,50 MB +,就不放上來(lái)了。


浙公網(wǎng)安備 33010602011771號(hào)