新时尚Windows8开发(24):文本呈现中的奥秘
TextBlock
这个东西算得上是最简单的文本呈现控件了,简单到什么程度呢?来,你也启动VS,新建一个项目,一边看一边动手试试吧。
要在TextBlock中显示简单文本,设置Text属性即可,如:
<TextBlock Text="猪,你今天吃早餐了没?" />
然后你运行一下,嗯,看到文本了吧。
这时候我想起来,这字体太小了,看不清楚,咋办,能不能修改字体大小,当然,看:
<TextBlock Text="猪,你今天吃早餐了没?" FontSize="32" />
修改FontSize后,你会看到字体大小有所变化了。那么,你肯定会想到,那能不能加粗?来,再看看:
<TextBlock Text="猪,你今天吃早餐了没?" FontSize="32" FontWeight="Bold" />
现在是不是看到明显的变化了?
那么,这个时候你可能又有新问题了,除了能够显示我们平时看到字符外,能不能显示其它字符。当然可以,看看下面的例子:
先打开“字符映射表”,用了Windows这么多年,不要问我怎么打开。
字体选择Segoe UI Symbol,记住了,不要选错,然后在符号列表中,拖动滚动条往下,找到你要的符号,在窗口的左下方可以看到编码。
然后,回到VS,输入以下XAML:
<TextBlock Text="" FontSize="65" FontFamily="Segoe UI Symbol" />
代码显示不出来,我只好截图了。
使用这些符号的时候要注意:
一,字体必须为Segoe UI Symbol;
二,要注意转义,输入字符时要以 &#x 开头,这是XML/HTML转义,比如,我们在字符映射表中看到某字符的编码为 U+ E109,在XAML中我们要替换为 
看清楚,后面还有一个英文的分号(;)。
当你运行应用程序时,你会看到以下效果。
这种符号不错吧,以后做图标就不用自己动手画了,直接用这些符号就行了,Windows Vista以后都能用这种字体。
如果你不会写这个转义,可以去抄,在哪呢?你看看你的“解决方案管理器”,看看下面图中标注的文件。
哈哈,我就说到这里,你一定会想到怎么去抄了,我相信你的悟性是很高的。
上面我们都看到TextBlock显示的简单文本,那么,能复杂一点吗?能。
对于有WPF基础的朋友,我这里提一下,到Windows.UI.Xaml.Documents命名空间下你就看到答案了。
在TextBlock中能换行吗?还记得HTML中的br元素吗?呵呵,XAML中也有,不信你看:
<TextBlock FontSize="32"> 第一行文本 <LineBreak /> 第二行文本 <LineBreak /> 第三行文本 </TextBlock>
效果嘛,自己运行一下看看。
下面又有难题了,能不能达到这种效果:我在里面显示“我们都是好孩子。”,我希望好孩子三个字加粗显示。答案肯定的,来,动手做做。
<TextBlock FontSize="32"> 我们都是<Bold>好孩子</Bold> </TextBlock>
这个效果不错吧。
再来看一个,我在里面显示“快乐编程,编程快乐”,我想把编程二字用绿色突出显示。
<TextBlock FontSize="32"> <Span Foreground="LightGreen">编程</Span>快乐, 快乐<Span Foreground="LightGreen">编程</Span>。 </TextBlock>
如果运行程序,就会看到下面的效果。
咱们再来一个综合一点的,
<TextBlock FontSize="32"> 我来自<Run FontSize="50" FontWeight="Black">何方</Run>, 像一颗<Italic FontSize="45" Foreground="Yellow">尘土</Italic>。 </TextBlock>
看看是什么样的结果?
哈哈,这个如何?
其实这里面,Run和Span元素区别不是非常大。
RichTextBlock
相对而言,RichTextBlock要稍为强大,看看下面这个例子。
<RichTextBlock> <Paragraph> <Span FontSize="40" FontWeight="Bold">造人</Span>li <LineBreak/> <Run FontSize="22">作者:张爱玲</Run> </Paragraph> <Paragraph TextIndent="36" FontSize="20"> 我一向是对于年纪大一点的人感到亲切,对于和自己差不多岁数的人稍微有点看不起,对于小孩则是尊重与恐惧,完全敬而远之。倒不是因为“后生可畏”。多半他们长大成人之后也都是很平凡的,还不如我们这一代也说不定。 </Paragraph> <Paragraph TextIndent="36" FontSize="20"> 小孩是从生命的泉源里分出来的一点新的力量,所以可敬,可怖。 </Paragraph> <Paragraph TextIndent="36" FontSize="20"> 小孩不像我们想象的那么糊涂。父母大都不懂得子女,而子女往往看穿了父母的为人。我记得很清楚,小时候怎样渴望把我所知道的全部吐露出来,把长辈们大大的吓唬一下。 </Paragraph> <Paragraph TextIndent="36" FontSize="20" Foreground="#FFB4C3F9" > 青年的特点是善忘,才过了儿童时代便把儿童心理忘得干干净净,直到老年,又渐渐和儿童接近起来,中间隔了一个时期,俗障最深,与孩子们完全失去接触——刚巧这便是生孩子的时候。 </Paragraph> <Paragraph TextIndent="36" FontSize="20"> 兽类有天生的慈爱,也有天生的残酷,于是在血肉淋漓的生存竞争中一代一代活了下来。“自然”这东西是神秘伟大不可思议的,但是我们不能“止于自然”。自然的作风是惊人的浪费——一条鱼产下几百万鱼子,被其他的水族吞噬之下,单剩下不多的几个侥幸孵成小鱼。为什么我们也要这样地浪费我们的骨血呢?文明人是相当值钱的动物,喂养,教养,在需要巨大的耗费。我们的精力有限,在世的时间也有限,可做,该做的事又有那么多——凭什么我们要大量制造一批迟早要被淘汰的废物? </Paragraph> <Paragraph> <InlineUIContainer> <HyperlinkButton FontSize="22" Content="点击这里查看原文" NavigateUri="http://meiwenrishang.com/post/2012-10-26/40040111222"/> </InlineUIContainer> </Paragraph> </RichTextBlock>
然后运行应用程序,你会看到有趣的效果。
RichTextBlock和TextBlock的使用方法差不多,只不过它较为丰富一些,如上面例子中,我们可以运用InlineUIContainer来放置我们的UI,上面例子中我放了一个HyperlinkButton,你可以放其他元素,只要是UIElement的子类就行了。
RichTextBlockOverflow
如果你细心观察一下,RichTextBlockOverflow和RichTextBlock 都有一个共同的属性——OverflowContentTarget,它的类型正是RichTextBlockOverflow,这个东西就是当文本太长了,RichEditBox显示不完时,就会放到RichTextBlockOverflow中,这个东东前面的文章中用过,就是那个类似报纸的多栏排版。
<Grid Margin="25"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <RichTextBlock Margin="15" Grid.Column="0" OverflowContentTarget="{Binding ElementName=of1}"> <Paragraph FontSize="24" TextIndent="46"> 生活在今日的世界上,心灵的宁静不易得。这个世界既充满着机会,也充满着压力。机会诱惑人去尝试,压力逼迫人去奋斗,都使人静不下心来。我不主张年轻人拒绝任何机会,逃避一切压力,以闭关自守的姿态面对世界。年轻的心灵本不该静如止水,波澜不起。世界是属于年轻人的,趁着年轻到广阔的世界上去闯荡一番,原是人生必要的经历。所须防止的只是,把自己完全交给了机会和压力去支配,在世界上风风火火或浑浑噩噩,迷失了回家的路途。每到一个陌生的城市,我的习惯是随便走走,好奇心驱使我去探寻这里的热闹的街巷和冷僻的角落。在这途中,难免暂时地迷路,但心中一定要有把握,自信能记起回住处的路线,否则便会感觉不踏实。我想,人生也是如此。你不妨在世界上闯荡,去建功创业,去探险猎奇,去觅情求爱,可是,你一定不要忘记了回家的路。这个家,就是你的自我,你自己的心灵世界。寻求心灵的宁静,前提是首先要有一个心灵。在理论上,人人都有一个心灵,但事实上却不尽然。有一些人,他们永远被外界的力量左右着,永远生活在喧闹的外部世界里,未尝有真正的内心生活。对于这样的人,心灵的宁静就无从谈起。一个人惟有关注心灵,才会因为心灵被扰乱而不安,才会有寻求心灵的宁静之需要。所以,具有过内心生活的禀赋,或者养成这样的习惯,这是最重要的。有此禀赋或习惯的人都知道,其实内心生活与外部生活并非互相排斥的,同一个人完全可能在两方面都十分丰富。区别在于,注重内心生活的人善于把外部生活的收获变成心灵的财富,缺乏此种禀赋或习惯的人则往往会迷失在外部生活中,人整个儿是散的。自我是一个中心点,一个人有了坚实的自我,他在这个世界上便有了精神的坐标,无论走多远都能够找到回家的路。换一个比方,我们不妨说,一个有着坚实的自我的人便仿佛有了一个精神的密友,他无论走到哪里都带着这个密友,这个密友将忠实地分享他的一切遭遇,倾听他的一切心语。如果一个人有自己的心灵追求,又在世界上闯荡了一番,有了相当的人生阅历,那么,他就会逐渐认识到自己在这个世界上的位置。世界无限广阔,诱惑永无止境,然而,属于每一个人的现实可能性终究是有限的。你不妨对一切可能性保持着开放的心态,因为那是人生魅力的源泉,但同时你也要早一些在世界之海上抛下自己的锚,找到最适合自己的领域。一个人不论伟大还是平凡,只要他顺应自己的天性,找到了自己真正喜欢做的事,并且一心把自己喜欢做的事做得尽善尽美,他在这世界上就有了牢不可破的家园。于是,他不但会有足够的勇气去承受外界的压力,而且会有足够的清醒来面对形形色色的机会的诱惑。我们当然没有理由怀疑,这样的一个人必能获得生活的充实和心灵的宁静。 </Paragraph> </RichTextBlock> <RichTextBlockOverflow x:Name="of1" Grid.Column="1" Margin="15" OverflowContentTarget="{Binding ElementName=of2}"/> <RichTextBlockOverflow x:Name="of2" Grid.Column="2" Margin="15"/> </Grid>
看上面的XAML,RichTextBlock放在平均被分为三列的Grid的第一列,但由于第一列的空间无法显示所有文本,所以将OverflowContentTarget属性设置为第二列中的RichTextBlockOverflow,而用完了第二列中的RichTextBlockOverflow,文本太长,还是无法显示完,这时候这个RichTextBlockOverflow的OverflowContentTarget就指向了第三列中的RichTextBlockOverflow。
这就是为什么RichTextBlock和RichTextBlockOverflow都有一个OverflowContentTarget属性的原因,而如果在代码中要判断文本是否溢出,可以访问HasOverflowContent属性,如果为真,即说明还有文本溢出,直到某个RichTextBlockOverflow的HasOverflowContent为假,才说明没有溢出的文本。
本例的运行结果如下图所示。