首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > windows >

新时尚Windows8开发(16):如何避免溢出文本

2012-10-11 
新时尚Windows8开发(16):如何处理溢出文本老周的博客http://blog.csdn.net/tcjiaan,转载请注明原作者和出

新时尚Windows8开发(16):如何处理溢出文本

老周的博客http://blog.csdn.net/tcjiaan,转载请注明原作者和出处。 

 

准确地说,本文是与各位分享一下小技巧。也不知道各位喜不喜欢。

嗯,废话就不说了,先看看我要实现什么样的运行结果。

新时尚Windows8开发(16):如何避免溢出文本

 

新时尚Windows8开发(16):如何避免溢出文本

 

是的,很像报纸的排版效果,那么,怎么做到的呢?

这就要提到一个类——RichTextBlockOverflow。他的用途就是,当RichTextBlock中的文本溢出后(就是当前RichTextBlock显示不完比较长的文本),可以在RichTextBlockOverflow上接着显示。

RichTextBlock的OverflowContentTarget属性设置为要接着显示文本的RichTextBlockOverflow,如果第一个RichTextBlockOverflow仍然不够用,则可以添加更多的RichTextBlockOverflow,只要把前一个的RichTextBlockOverflow的OverflowContentTarget属性设置为新的RichTextBlockOverflow,以此类推。

要判断文本是否溢出,可以通过HasOverflowContent属性获得。

 

好了,大概原理说了,下面就是动手实现了。

 

1、启动Visual Studio for Win 8 ,新建一个项目。

2、MainPage.xaml比较简单,按钮是为了选取一个较长的文本文件,文本框用于输入字体大小。用于排列文本的是一个StackPanel。

<Page    x:Class="App1.MainPage"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:local="using:App1"    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    mc:Ignorable="d">    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">        <Grid.RowDefinitions>            <RowDefinition Height="auto"/>            <RowDefinition Height="*"/>        </Grid.RowDefinitions>        <StackPanel Grid.Row="0" Orientation="Horizontal" Margin="25">            <Button Content="打开文件" Click="onClick"/>            <TextBlock Text="字体大小" Margin="37,0,0,0" FontSize="24" VerticalAlignment="Center"/>            <TextBox Name="txtSize" VerticalAlignment="Center" Margin="8,0,0,0" Width="130" Text="16">                <TextBox.InputScope>                    <InputScope>                        <InputScope.Names>                            <InputScopeName NameValue="Number"/>                        </InputScope.Names>                    </InputScope>                </TextBox.InputScope>            </TextBox>        </StackPanel>        <ScrollViewer Margin="15" Grid.Row="1" HorizontalScrollBarVisibility="Auto" HorizontalScrollMode="Auto">            <StackPanel  Name="stPanel" Orientation="Horizontal" />        </ScrollViewer>    </Grid></Page>


3、对于后台的代码,先贴出完整的吧。

using System;using System.Collections.Generic;using System.IO;using System.Linq;using Windows.Foundation;using Windows.Foundation.Collections;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Controls.Primitives;using Windows.UI.Xaml.Data;using Windows.UI.Xaml.Input;using Windows.UI.Xaml.Media;using Windows.UI.Xaml.Navigation;using Windows.Storage;using Windows.Storage.Streams;using Windows.Storage.Pickers;using Windows.UI.Xaml.Documents;namespace App1{    public sealed partial class MainPage : Page    {        const double CT_WIDTH = 400d; //文本块的宽度        const double CT_HEIGHT = 500d; //文本块的高度        const double CT_MARGIN = 25d; //文本块的边距        public MainPage()        {            this.InitializeComponent();        }        private async void onClick(object sender, RoutedEventArgs e)        {            // 从文本文件中读取内容            FileOpenPicker opPicker = new FileOpenPicker();            opPicker.FileTypeFilter.Add(".txt");            opPicker.CommitButtonText = "打开";            opPicker.SuggestedStartLocation = PickerLocationId.Desktop;            StorageFile file = await opPicker.PickSingleFileAsync();            if (file != null)            {                using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read))                {                    // 从流中读取文本,考虑utf-8读出来的是乱码,                    // 改用Stream类来读取                    // 使用gb2312编码格式                    string msg = string.Empty;                    using (Stream strm = stream.AsStream())                    {                        StreamReader render = new StreamReader(strm, System.Text.Encoding.GetEncoding("gb2312"));                        msg = render.ReadToEnd();                    }                    // 去掉特殊的换行符                    msg = msg.Replace(" ", "").Replace("\n", "").Replace("\r","\n").Replace("\t","");                    stPanel.Children.Clear();                    // 为了支持文本分块,使用RichTextBlock                    RichTextBlock tbContent = new RichTextBlock();                    tbContent.Width = CT_WIDTH;                    tbContent.Height = CT_HEIGHT;                    tbContent.TextWrapping = TextWrapping.Wrap;                    tbContent.Margin = new Thickness(CT_MARGIN);                    Paragraph ph = new Paragraph();                    ph.TextIndent = 33;                    Run txtRun = new Run();                    txtRun.Text = msg;                    ph.Inlines.Add(txtRun);                    tbContent.Blocks.Add(ph);                    tbContent.FontSize = Convert.ToDouble(txtSize.Text);                    stPanel.Children.Add(tbContent);                    // 更新一下状态,方便获取是否有溢出的文本                    tbContent.UpdateLayout();                    bool isflow = tbContent.HasOverflowContent;                    // 因为除了第一个文本块是RichTextBlock,                    // 后面的都是RichTextBlockOverflow一个一个接起来的                    // 所以我们需要两个变量                    RichTextBlockOverflow oldFlow = null, newFlow = null;                    if (isflow)                    {                        oldFlow = new RichTextBlockOverflow();                        oldFlow.Width = CT_WIDTH;                        oldFlow.Height = CT_HEIGHT;                        oldFlow.Margin = new Thickness(CT_MARGIN);                        tbContent.OverflowContentTarget = oldFlow;                        stPanel.Children.Add(oldFlow);                        oldFlow.UpdateLayout();                        // 继续判断是否还有溢出                        isflow = oldFlow.HasOverflowContent;                    }                    while (isflow)                    {                        newFlow = new RichTextBlockOverflow();                        newFlow.Height = CT_HEIGHT;                        newFlow.Width = CT_WIDTH;                        newFlow.Margin = new Thickness(CT_MARGIN);                        oldFlow.OverflowContentTarget = newFlow;                        stPanel.Children.Add(newFlow);                        newFlow.UpdateLayout();                        // 继续判断是否还有溢出的文本                        isflow = newFlow.HasOverflowContent;                        // 当枪一个变量填充了文本后,                        // 把第一个变量的引用指向当前RichTextBlockOverflow                        // 确保OverflowContentTarget属性可以前后相接                        oldFlow = newFlow;                    }                }            }        }    }}


其实,重点就是循环加入文本块的地方,代码中我也做了注释。

 

热点排行