鸿志之家

让我们一起来学习体验微软Silverlight的魅力
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Silverlight RichTextBox 保存格式解决方案

Posted on 2012-02-01 11:03  大漠、天使、飞烟  阅读(250)  评论(0)    收藏  举报

在新闻、留言板等系统中一种常见的需求是,保存用户的输入到数据库,显示时不能丢失格式。

转载请注明出处:http://www.cnblogs.com/brooks-dotnet/archive/2010/11/10/1874181.html

 

Silverlight 4 提供了一个RichTextBox控件,可以输入一些富文本信息,如超链接、图片等,并可以设置格式。RichTextBox提供了一个Xaml 属性,获取或设置 RichTextBox 中内容的 XAML 表示形式。

Xaml 属性返回的 XAML 字符串将只包括以下元素:(摘自MSDN)

虽然已经包括了大部分的元素,但是缺少一个关键的元素:图片。很多信息都是图文并茂的,这样用RichTextBox显示图片就有点困难了。且由于Silverlight是客户端技术,对访问本地资源有严格的安全性限制,Silverlight 4 只有在提升权限的情况下才可以访问系统剪切板中的部分元素。在Silverlight 4 中,只能粘贴剪切板中的文字信息,不能粘贴图片,且内容格式全部丢失。经过多方查找资料、测试,我找到两种解决方案。

一、第三方组件:SLaBv0.9

这里查看作者的博客。RichTextBox还有一个属性:Blocks。

Blocks 属性是 RichTextBox 的内容属性。它是 Paragraph 元素的集合。每个 Paragraph 元素中的内容都可包含下列元素:

InlineUIContainer可包含 UIElement,例如 Image Button

Span Inline 元素的集合。

这个组件的作者实现了一个Xaml的序列化、反序列化类,能够从Blocks中提取出图片,在需要时显示,可以参考他的源代码。

我写了一个简单的测试程序,在RichTextBox中输入内容后,点击预览按钮查看:

 

将RichTextBox的Blocks作为属性传递给预览窗口:

this.PreviewWindow =new QuestionPreview(this.txt问题描述.Blocks);
this.PreviewWindow.Show();

 

 

 

在预览窗口中进行解析:

代码
privatevoid fnBlockParse()
{
UiXamlSerializer uxs
=new UiXamlSerializer();
ObservableObjectCollection ooc
=new ObservableObjectCollection();
foreach (Block b inthis.blocks)
{
ooc.Add(b);
}
string xaml = uxs.Serialize(ooc);
ObservableObjectCollection bc
= (ObservableObjectCollection)XamlReader.Load(xaml);
this.txt预览.Blocks.Clear();
foreach (Block b in bc)
{
this.txt预览.Blocks.Add(b);
}
}

 

 

 

最终运行效果:

 

这种方案的好处是非常简洁,如果内容不需要保存到数据库,只用来显示,那将非常好。但是若需要保存到数据库,且不丢失格式,就很困难了。下面我们来看第二种解决方案,可以完美的解决这个问题。

 

二、Telerik的商业组件

Telerik是一个专业的组件、控件公司,其官方主页是:http://www.telerik.com/

除了Silverlight,该公司还开发了WinForm、WPF、ASP.NET AJAX、ASP.NET MVC等很多组件,界面非常华丽,源码是学习UI的好示例。

我使用的是目前的最新版本:RadControls for Silverlight version: 2010.2 924 (Sep 24, 2010),可以在这里下载试用版本(需要先注册):

安装完后会给VS2010添加一个插件,且工具箱中包含了其所有的控件:

 

下面是我的测试项目:

数据库使用的SQLite,用ADO.NET For SQLite、WCF做的数据访问。

使用了RadRichTextBoxRibbonUIRadRichTextBox两个控件,保存、显示图片的关键代码是:

代码
privatestring fnExportToXAML(RadDocument document)
{
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;
}

 

 

 

数据库中存的是Telerik的Xaml:

可以看到图片已经编码过了,所有的格式都会保存。

这种方案的优点是可以保存完整的格式信息,包括图片等。缺点是效率不高,当图片很多很大时,存取将会很慢。

以上是我查找到的解决方案,若你有别的方法,欢迎分享。

注:这个项目是我给公司做的一个帮助中心,用来查看常见问题的解决方法,有很多功能尚未完善。

项目很大,50 MB +,就不放上来了。

分类: SilverLight