《RichTextBox 》——— Silverlight中的RichTextBox
在Silverlight4版本中,RichTextBox这个控件算是很受期待的控件了,希望通过这篇文章让你对该控件有所了解。
在Sl中,有TextBox,TextBlock,RichTextBox这3个核心的文本控件,从表面上看,RichTextBox看起来和一个普通的TextBox并
没有太多的区别,实际上它提供了诸如格式化文本,段落,超链接,内联图像这些功能,它甚至可以显示任何UIElement,比如DataGrid。
MSDN有关于RichTextBox内容模型的一个关系图
RichTextBox的内容属性是Blocks,这是一个Paragraph的集合,这些Paragraph可以包含Inline元素派生的元素。 比如Run,
Span,Bold,Italic,Hyperlink,InlineUIContainer,其实从图中你可能会注意到Hyperlink比较特殊,它不能包含其它Inline类型的元素。
下面熟悉RichTextBox中一些简单的属性:
添加RichTextBox:
1 <RichTextBox AcceptsReturn="True" x:Name="rbtMyRichTextBox">
RichTextBox常用的属性包括AcceptReturn和IsReadOnly属性,只有在只读模式下,UI元素才是可用的。
添加元素:
前面已经提到,RichTextBox包含了Paragraph集合,所以我们可以轻易添加任何内联元素,那么这里我们看一看在一个Paragraph
中添加多个元素的Code
1 Paragraph prgParagraph = new Paragraph(); 2 Run rnMyText = new Run(); 3 rnMyText.Text = "This is some example text with a "; 4 prgParagraph.Inlines.Add(rnMyText); 5 Hyperlink lnkSSLink = new Hyperlink(); 6 lnkSSLink.Inlines.Add("link to Silverlight Show"); 7 lnkSSLink.NavigateUri = new Uri("http://www.cnblogs.com"); 8 prgParagraph.Inlines.Add(lnkSSLink); 9 rbtMyRichTextBox.Blocks.Add(prgParagraph);
上面的代码中,添加了一些文本和一个超链接,那么首先要做的是实例化一个Paragraph,在这个Paragraph中,我们添加了文本和
超链接,这些对象被添加到该Paragraph中的Inlines集合中,最后将这个Paragraph添加到了RichTextBox中
格式文本对象:
Run元素只能包含非格式化的文本,如果想要对文本进行格式化,那么可以采用变通的方式,即将Run元素包含在内联的格式元素中
1 Paragraph prgParagraph = new Paragraph(); 2 Bold bldText = new Bold(); 3 bldText.Inlines.Add(new Run() { Text = "This is some example text in bold" }); 4 Italic itlText = new Italic(); 5 itlText.Inlines.Add(new Run() { Text = "This is some example text in italics" }); 6 Underline unText = new Underline(); 7 unText.Inlines.Add(new Run() { Text = "This is some example text, underlined" }); 8 Bold bldTextWithItalic = new Bold(); 9 bldTextWithItalic.Inlines.Add(new Italic() { Inlines = { new Run(){ Text = "This is some example text, bold and italic" } } }); 10 prgParagraph.Inlines.Add(bldText); 11 prgParagraph.Inlines.Add(new LineBreak()); 12 prgParagraph.Inlines.Add(itlText); 13 prgParagraph.Inlines.Add(new LineBreak()); 14 prgParagraph.Inlines.Add(unText); 15 prgParagraph.Inlines.Add(new LineBreak()); 16 prgParagraph.Inlines.Add(bldTextWithItalic); 17 rbtMyRichTextBox.Blocks.Add(prgParagraph);
上面的代码分别实现了文本的加粗,倾斜,下滑线功能,和添加元素的代码没有太大区别
添加InlineUIContainer:
顾名思义,这个元素就是UI元素的容器,当我们想要在内容中添加Image,DataGrid这些元素的时候,它非常的方便,步骤也是和其它内联元素一样的
先创建一个InlineUIContainer,然后在容器中添加UIElement,把这个容器添加到Paragraph中
1 InlineUIContainer iuicContainer = new InlineUIContainer(); 2 DataGrid dtgGrid = new DataGrid(); 3 dtgGrid.AutoGenerateColumns = true; 4 dtgGrid.Width = 400; 5 dtgGrid.Height = 200; 6 dtgGrid.ItemsSource = ... 7 iuicContainer.Child = dtgGrid; 8 Paragraph prgParagraph = new Paragraph(); 9 prgParagraph.Inlines.Add(iuicContainer); 10 rbtMyRichTextBox.Blocks.Add(prgParagraph);
上面的CODE如果改成XAML声明:
1 <RichTextBox AcceptsReturn="True" 2 Margin="5" 3 x:Name="rbtMyRichTextBox"> 4 <Paragraph> 5 <InlineUIContainer> 6 <Image Source="Assets/logo.png" Width="100"></Image> 7 </InlineUIContainer> 8 </Paragraph> 9 </RichTextBox>
通过上面的内容已经对RichTextBox有了基本的了解,其实之前我们都是通过编程的方式加入这些元素,但是更为常见的场景是
用户可以通过选择某些文本,并对选中的文本进行加粗等操作,RichTextBox提供了一个类型为TextSelection的Selection属性,
它包含了当前被选择的文本,然后我们可以通过GetPropertyValue和ApplyPropertyValue方法对选择的文本进行操作
操作Selection:
1 if (rbtMyRichTextBox != null && rbtMyRichTextBox.Selection.Text.Length > 0) 2 { 3 if (rbtMyRichTextBox.Selection.GetPropertyValue(Run.FontWeightProperty) is FontWeight 4 && ((FontWeight)rbtMyRichTextBox.Selection.GetPropertyValue(Run.FontWeightProperty)) == FontWeights.Normal) 5 { 6 rbtMyRichTextBox.Selection.ApplyPropertyValue(Run.FontWeightProperty, FontWeights.Bold); 7 } 8 else 9 { 10 rbtMyRichTextBox.Selection.ApplyPropertyValue(Run.FontWeightProperty, FontWeights.Normal); 11 } 12 } 13 if (rbtMyRichTextBox != null) 14 { 15 rbtMyRichTextBox.Focus(); 16 }
上面的代码中,我们获取了选中文本的FontWeight属性,通过检查它是Normal还是Bold改变其值,这里的逻辑也可以用在
FontSize等其它的属性上。
简单的复制,剪切,粘贴功能:
Sl4支持Clipboard功能,所以通过访问Clipboard我们可以很容易实现剪切,复制功能
1 private void Copy_Click(object sender, RoutedEventArgs e) 2 { 3 Clipboard.SetText(rbtMyRichTextBox.Selection.Text); 4 rbtMyRichTextBox.Focus(); 5 } 6 private void Cut_Click(object sender, RoutedEventArgs e) 7 { 8 Clipboard.SetText(rbtMyRichTextBox.Selection.Text); 9 rbtMyRichTextBox.Selection.Text = ""; 10 rbtMyRichTextBox.Focus(); 11 }
上面的代码分别演示如何对RichTextBox中被选中的文本进行复制,剪切
1 private void Paste_Click(object sender, RoutedEventArgs e) 2 { 3 rbtMyRichTextBox.Selection.Text = Clipboard.GetText(); 4 rbtMyRichTextBox.Focus(); 5 }
复制的时候,如果RichTextBox没有选择任何元素,那么剪切板上的文本将显示在鼠标的当前位置上。注意的是,Cilpboard只能保护简单
的文本,所以当粘贴,复制的时候会丢失之前格式化的信息。
保存内容为文件:
RichTextBox提供了一个名为Xaml的属性,通过这个属性可以很方便的将内容保存为文件
1 private void Save_Click(object sender, RoutedEventArgs e) 2 { 3 var uiElements = from block in rbtMyRichTextBox.Blocks 4 from inline in (block as Paragraph).Inlines 5 where inline.GetType() == typeof(InlineUIContainer) 6 select inline; 7 if (uiElements.Count() != 0) 8 { 9 MessageBox.Show("UIElements cannot be saved"); 10 return; 11 } 12 SaveFileDialog sfdSaveXaml = new SaveFileDialog(); 13 sfdSaveXaml.DefaultExt = ".sav"; 14 sfdSaveXaml.Filter = "Saved rtb files|*.rtb"; 15 if (sfdSaveXaml.ShowDialog().Value) 16 { 17 using (FileStream fs = (FileStream)sfdSaveXaml.OpenFile()) 18 { 19 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); 20 byte[] buffer = enc.GetBytes(rbtMyRichTextBox.Xaml); 21 fs.Write(buffer, 0, buffer.Length); 22 fs.Close(); 23 } 24 } 25 }
因为RichTextBox不支持保存InlineUIContainer的元素,所以上面的代码中先将其排除,然后通过FileStream保存
打开文件:
这个与保存文件过程是相反的,只要将RichTextBox的Xaml属性设置为读出的XAML
1 private void Open_Click(object sender, RoutedEventArgs e) 2 { 3 OpenFileDialog ofdOpenXaml = new OpenFileDialog(); 4 ofdOpenXaml.Multiselect = false; 5 ofdOpenXaml.Filter = "Saved rtb files|*.rtb"; 6 if (ofdOpenXaml.ShowDialog().Value) 7 { 8 FileInfo fiXamlFile = ofdOpenXaml.File; 9 StreamReader sr = fiXamlFile.OpenText(); 10 rbtMyRichTextBox.Xaml = sr.ReadToEnd(); 11 sr.Close(); 12 } 13 }
上面的保存,读取的文件只支持rtb格式的,其实可以使用其它的格式,当然肯定需要额外的编码,比如你打开一个文本文件,那么
首先需要你创建所必须的Run标记。总之,你需要将内容转换成Xaml格式。
对于保存文件,可以看看CodePlex上一个开眼项目:WordToXaml
这篇文章是参考的国外这篇RichTextBox,文中的源码可以在其中找到。
作者:wpf之家