如何在报纸中将长文本分成列?

时间:2016-08-02 12:12:42

标签: c# wpf uwp

是否有任何框架支持,或者我应该为此编写自己的代码?

阅读长行文字很困难并导致疲劳。可读文本应由短行组成。问题是,在我的应用程序中,我有大的水平空间来覆盖文本。

在良好的应用中,表示层应该独立于数据层,在这种情况下是文本。所以我需要多列文本布局,但是将文本分成列必须由程序完成,它不能被硬编码。

在HTML / CSS3中,这很容易。在XAML中是否有一些支持?

如果没有,你知道一些能够显示多列布局的库吗?

最好是控件可以决定是否使用多列。如果矩形比较宽 - 那么是的。如果它比更宽更高 - 那么没有。

4 个答案:

答案 0 :(得分:1)

您必须使用DocumentViewer,这是一个专门用于呈现文档的WPF控件。阅读这篇文章:https://msdn.microsoft.com/en-us/library/aa970909(v=vs.110).aspx

答案 1 :(得分:1)

感谢所有人,您的回答使我能够快速生成基本的WPF代码示例:

<Window x:Class="TextFlow.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TextFlow"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525" Background="Black" Foreground="Gray">
    <Window.Resources>
        <ControlTemplate x:Key="NoPageControls" TargetType="{x:Type FlowDocumentPageViewer}">
            <AdornerDecorator>
                <DocumentPageView FlowDocumentPageViewer.IsMasterPage="True" />
            </AdornerDecorator>
        </ControlTemplate>
    </Window.Resources>
    <Grid>
        <FlowDocumentPageViewer Template="{StaticResource NoPageControls}">
            <FlowDocument ColumnWidth="200" FontFamily="Segoe UI" FontSize="10">
                <Paragraph>
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus vitae purus pellentesque, ultricies magna a, egestas nisl. Quisque eu risus quis elit posuere imperdiet. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla sagittis, felis at luctus tempus, metus dolor ultricies mi, vitae aliquet justo libero non arcu. Suspendisse potenti. Maecenas luctus rutrum lorem non congue. Sed vitae blandit felis. Nullam eu leo non dui vulputate tincidunt id eu odio. Etiam risus velit, consequat vel tortor in, condimentum vestibulum est. Sed maximus elementum erat nec fermentum.
                </Paragraph>
                <Paragraph>
                    Donec nec ex dignissim, ornare arcu eu, fermentum ipsum. Cras ullamcorper blandit quam, in pulvinar justo sodales quis. Vivamus sed tincidunt augue, nec convallis lorem. Phasellus lobortis nibh sem, sit amet suscipit tellus dapibus at. Aliquam arcu tellus, aliquet at cursus sodales, ornare a sem. Morbi sollicitudin orci et hendrerit ullamcorper. In non faucibus risus. Morbi eget metus pharetra quam consequat pretium quis ac enim. Integer scelerisque elit malesuada pharetra condimentum. Aliquam erat volutpat. Ut at consectetur erat. Phasellus pulvinar consequat erat quis placerat. Cras tortor mi, tempor ultricies sodales at, faucibus quis lacus. Morbi semper vestibulum odio eget tempor. Praesent at mollis erat. Praesent sollicitudin nulla sit amet magna fermentum porta.
                </Paragraph>
                <Paragraph>
                    Proin tincidunt ex interdum, sodales leo non, fringilla tellus. Vestibulum eget posuere purus, et aliquam arcu. Sed ac dolor ullamcorper, rutrum sapien sit amet, convallis enim. Mauris a faucibus augue. Morbi porta nunc ac ligula suscipit consequat. Curabitur in interdum elit. Pellentesque tempor tempor tellus, ut bibendum elit consequat vitae. Fusce commodo ac nunc ut pretium. Vestibulum ut vulputate est. Nullam pharetra ornare elementum. Nullam eros nunc, tincidunt at porta sit amet, rutrum in mauris. Vivamus id ante sit amet velit pulvinar interdum. Cras efficitur egestas nunc id tempor. Vivamus eu enim vitae lorem molestie tincidunt nec et ex. Integer nec turpis nisi.
                </Paragraph>
            </FlowDocument>
        </FlowDocumentPageViewer>
    </Grid>
</Window>

是的,仍然需要一些手动处理,但是当我只想以可读的方式显示一些本地化描述时,这是非常好的。

一些自动操作(如确定是否需要列或它们应该有多宽)可以很容易地添加到此,但我会尽可能简单地保留示例。必须应用控件模板才能隐藏页面控件。如果文本较大且不适合一页 - 您只需保留原始模板。

很遗憾,这在UWP中无法使用。是吗?

所以,我们需要更深入。没有UWP的帮助,很好,让我们做一个至少可以做WPF控制的控件,对吗?

没有进一步的干预 - ReadableBlock控制:

using System.Collections.Generic;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Documents;

namespace ReadableBlockDemo.Controls {
    public sealed class ReadableBlock : ContentControl {

        public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(ReadableBlock), null);

        public static readonly DependencyProperty TextAlignmentProperty =
            DependencyProperty.Register("TextAlignment", typeof(TextAlignment), typeof(ReadableBlock), new PropertyMetadata(TextAlignment.Left));

        public static readonly DependencyProperty ColumnsProperty =
            DependencyProperty.Register("Columns", typeof(int), typeof(ReadableBlock), new PropertyMetadata(1));

        public static readonly DependencyProperty ColumnSpacingProperty =
            DependencyProperty.Register("ColumnSpacing", typeof(double), typeof(ReadableBlock), new PropertyMetadata(10d));

        public string Text {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        public TextAlignment TextAlignment {
            get { return (TextAlignment)GetValue(TextAlignmentProperty); }
            set { SetValue(TextAlignmentProperty, value); }
        }

        public int Columns {
            get { return (int)GetValue(ColumnsProperty); }
            set { SetValue(ColumnsProperty, (int)value); }
        }

        public double ColumnSpacing {
            get { return (double)GetValue(ColumnSpacingProperty); }
            set { SetValue(ColumnSpacingProperty, (double)value); }
        }

        public new string Content {
            get { return (string)GetValue(ContentProperty); }
            set { base.Content = null; SetValue(ContentProperty, Text = (string)value); RenderText(); }
        }

        private StackPanel Container => base.Content as StackPanel;

        private double AvailableWidth;

        private double AvailableHeight;

        private TextBlock[] Blocks;

        private double ColumnWidth;

        private bool IsTextRenderingAvailable;

        public ReadableBlock() {
            Loaded += ReadableBlock_Loaded;
        }

        private void ReadableBlock_Loaded(object sender, RoutedEventArgs e) {
            LayoutUpdated += ReadableBlock_LayoutUpdated;
            InvalidateArrange();
        }

        private void ReadableBlock_LayoutUpdated(object sender, object e) {
            if (ActualWidth != AvailableWidth || ActualHeight != AvailableHeight) OnAvailableSizeChanged();
        }

        private void OnAvailableSizeChanged() {
            IsTextRenderingAvailable = true;
            AvailableWidth = ActualWidth;
            AvailableHeight = ActualHeight;
            double n = Columns;
            double s = ColumnSpacing;
            ColumnWidth = (AvailableWidth - ((n - 1d) * s)) / n;
            if (Blocks == null) CreateColumns();
            RenderText();
        }

        private void CreateColumns() {
            var container = new StackPanel { Orientation = Orientation.Horizontal };
            var columns = Columns;
            var spacing = ColumnSpacing;
            var blocks = new List<TextBlock>();
            TextBlock block;
            for (int i = 0; i < columns; i++) {
                blocks.Add(block = new TextBlock { TextWrapping = TextWrapping.Wrap, TextAlignment = TextAlignment, Width = ColumnWidth, Height = AvailableHeight });
                if (i > 0) block.Margin = new Thickness(spacing, 0, 0, 0);
                container.Children.Add(block);
            }
            base.Content = container;
            Blocks = blocks.ToArray();
        }

        private int GetSplitOffset(string text) {
            var m = new TextBlock { FontFamily = FontFamily, FontSize = FontSize, TextWrapping = TextWrapping.Wrap, TextAlignment = TextAlignment };
            m.Text = text;
            m.Measure(new Size(ColumnWidth, double.PositiveInfinity));
            if (m.DesiredSize.Height < AvailableHeight) return -1;
            var p = m.ContentStart;
            var r = p.GetCharacterRect(LogicalDirection.Forward);
            for (int i = 0, l = text.Length; i < l && r.Bottom < AvailableHeight; i++) {
                p = p.GetPositionAtOffset(1, LogicalDirection.Forward);
                r = p.GetCharacterRect(LogicalDirection.Forward);
            }
            return p.Offset - 2;
        }

        private bool SetBlock(int i, string text) {
            if (i >= Blocks.Length) return false;
            var block = Blocks[i];
            block.Width = ColumnWidth;
            block.Height = AvailableHeight;
            block.Text = text;
            return true;
        }

        private void RenderText() {
            if (!IsTextRenderingAvailable || Text == null) return;
            int i = 0, splitOffset = 0, n = Blocks.Length;
            string text = Text;
            for (i = 0; i < n; i++) Blocks[i].Text = "";
            for (i = 0; i < n; i++) {
                splitOffset = GetSplitOffset(text);
                if (splitOffset > 0) {
                    if (!SetBlock(i, text.Substring(0, splitOffset))) return;
                    if (!SetBlock(i + 1, text = text.Substring(splitOffset))) return;
                }
                else {
                    SetBlock(i, text);
                    return;
                }
            }
        }

    }

}

和一些XAML测试它:

<Page
    x:Class="ReadableBlockDemo.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ReadableBlockDemo"
    xmlns:Controls="using:ReadableBlockDemo.Controls"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="#444"
    Foreground="Gray"
    >
    <Grid>
        <Controls:ReadableBlock Columns="4" ColumnSpacing="25" TextAlignment="Justify" Margin="25">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tempor ipsum massa, ac lacinia libero sagittis lobortis. Donec pretium ex quis massa eleifend dignissim. Maecenas quis est odio. Proin facilisis mollis purus, vitae dapibus lacus interdum ac. Sed molestie id lorem vel volutpat. Ut vitae quam sem. Pellentesque convallis elementum ipsum commodo porttitor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis sed porta eros. Pellentesque eget dolor euismod, fermentum orci vitae, ullamcorper mauris. Aliquam tempus hendrerit sollicitudin. Nunc sed erat quis ligula dictum convallis. Mauris eget finibus odio. Aenean sagittis congue purus, at elementum mi rhoncus ut. Suspendisse hendrerit dictum eleifend. Nullam scelerisque, eros ac euismod semper, velit sapien tincidunt purus, a tempus enim ante ut turpis. In vehicula arcu vitae nunc eleifend, id porta felis consequat.
            Praesent vel tincidunt dui. Ut ut turpis lacus. Nullam accumsan laoreet elit eu suscipit. Cras aliquet pellentesque fringilla. Nullam ut consectetur nisi, non tristique quam. Suspendisse vitae gravida ipsum. Fusce ac enim non arcu rutrum sollicitudin. Aliquam in odio id tellus venenatis egestas et quis sapien. Etiam scelerisque ultrices tellus, quis dignissim leo gravida id.
            Etiam ut elit tortor. Fusce fringilla accumsan urna eu viverra. Nunc porttitor lorem vitae magna ultrices lacinia. Etiam posuere sed dui nec gravida. Aenean fermentum turpis vehicula, blandit arcu id, mollis nulla. Praesent laoreet tellus vitae lectus consequat interdum. Duis interdum feugiat interdum.
            Nam ut maximus est. Vestibulum sagittis eros ut diam ultrices eleifend. Praesent purus quam, luctus quis arcu at, interdum dapibus leo. Vivamus eget massa in leo malesuada egestas quis eget ipsum. Etiam consequat ullamcorper est, in ultricies lacus lobortis commodo. Nullam feugiat libero vitae convallis pellentesque. Pellentesque vitae tristique massa. In sollicitudin pretium nisl sit amet dignissim. Curabitur sodales fringilla ex, sit amet gravida lacus dignissim tempus. Aenean libero lectus, viverra eu eros in, pellentesque accumsan elit. Proin porttitor metus nulla, sit amet vulputate mauris finibus ut. Phasellus viverra risus sapien, eget sodales neque rhoncus vel. Nam quis ullamcorper nulla.
            Duis sed ante dignissim, consequat orci in, iaculis nisi. Etiam nec interdum magna. Donec pharetra fermentum mi, eu aliquet diam hendrerit eget. Aenean vitae ligula sem. Sed at dignissim lorem. Proin vulputate massa eleifend, sagittis leo sit amet, condimentum mi. Curabitur nec vulputate nibh. Nunc ut dictum sapien. Praesent eu rhoncus lectus. Nullam eu auctor dui. Sed accumsan leo et ligula tempus semper. Suspendisse sed magna ut lectus pharetra malesuada.
            Nullam pretium ligula non elit tempus imperdiet. In convallis a mauris vitae venenatis. Morbi pulvinar placerat ante nec tristique. Sed sodales leo in erat fermentum malesuada. Nullam vel turpis ut nulla tempus faucibus. Fusce dictum odio vel felis fringilla, a iaculis urna ultricies. Sed at mauris dolor. Aenean et vulputate libero, at sollicitudin leo. Morbi pretium gravida turpis ac bibendum. Aliquam lacinia mauris ut ante pharetra accumsan. Ut hendrerit, diam in iaculis egestas, justo magna pulvinar sapien, ut pellentesque purus orci id magna. Morbi egestas vestibulum dui, a ullamcorper turpis. Aenean molestie luctus lacus, vel pellentesque elit tincidunt sit amet. Suspendisse eu cursus enim. In eu libero a ipsum interdum aliquam quis blandit quam.
            Fusce tortor nisi, pretium non dolor vitae, pretium condimentum ex. Cras facilisis odio tortor, et scelerisque quam volutpat non. Nam fermentum, velit in molestie venenatis, odio ante dapibus nulla, sed luctus ex urna sit amet lectus. Donec sit amet eros at nulla tempor venenatis. Cras nec purus porttitor dolor pretium auctor. Mauris sed ligula eget libero egestas tempus quis eu ipsum. Duis fermentum egestas libero. Praesent a mi ut felis facilisis pharetra id vel nulla.
            Aenean dolor leo, placerat ac lobortis ut, tincidunt sit amet ex. Pellentesque at convallis massa. Vivamus fermentum eu augue vel sollicitudin. Donec dictum libero sem, et bibendum ex ultricies eget. Sed eu feugiat odio. Sed eget ex congue, dapibus magna ac, finibus diam. Nunc sollicitudin euismod dictum. Nullam rutrum mauris ut ipsum finibus, et euismod arcu sodales. In pellentesque molestie nunc, eget pellentesque metus varius et. Morbi augue nisl, aliquet eu scelerisque at, dictum eu elit. Quisque id ex quis urna facilisis rutrum nec in risus. Sed lorem justo, tempus at ante quis, cursus ultrices tellus. Donec lacinia varius lacus, vitae molestie velit auctor vitae. Aenean vulputate ullamcorper justo sit amet consectetur. Fusce vel risus mattis augue ultrices molestie. Donec sed rhoncus diam.
            Nulla condimentum cursus massa semper suscipit. Cras non porta diam. Donec sed erat eu lectus vehicula hendrerit. Proin a ex tellus. Morbi aliquet dolor in ante lobortis, consequat aliquam dolor cursus. Sed molestie odio massa, a consectetur turpis pellentesque eget. Maecenas quis pharetra ligula, non rutrum libero. Aenean maximus nibh vel nisl elementum imperdiet. Integer et urna eu velit porttitor eleifend. Nunc et pharetra nisl. Nulla porttitor pellentesque mi. Suspendisse porta a ipsum at interdum.
        </Controls:ReadableBlock>
    </Grid>
</Page>

行。没有滚动,没有格式化,只是基础。只是列,固定金额。 未经过彻底测试,因此可能存在一两个错误,但它应该可以与示例文本一起使用。

我认为如果我们允许格式化文本会更难。或者可能不是?好吧,这个例子拆分了普通的字符串。 TextBlock公开ContentStart属性,允许我们获取TextBlock中所有字符的像素坐标 - 如果仅测量它。因此,我们创建了不可见的TextBlock - 将其宽度设置为列宽,我们搜索字符落在可用高度之外的索引。

它打败了我如何扩展这个黑客来支持格式化文本,我认为这个问题将变得非常“非平凡”;)

答案 2 :(得分:1)

您可以使用VisualStateManager自适应地创建多个列视图。假设您希望将文本显示在三个不同的列中,然后将文本分成三个部分,并将它们设置为XAML中表示元素的数据源。

<Page
x:Class="App7.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AdaptiveLayoutExample"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Grid Name="LayoutRoot" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="VisualStateGroup">
            <VisualState x:Name="Wide">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="650" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="First.(Grid.Row)" Value="0" />
                    <Setter Target="First.(Grid.Column)" Value="0" />
                    <Setter Target="Second.(Grid.Row)" Value="0" />
                    <Setter Target="Second.(Grid.Column)" Value="1" />
                    <Setter Target="Third.(Grid.Row)" Value="0" />
                    <Setter Target="Third.(Grid.Column)" Value="2" />

                    <Setter Target="First.(Grid.ColumnSpan)" Value="1" />
                    <Setter Target="Second.(Grid.ColumnSpan)" Value="1" />
                    <Setter Target="Third.(Grid.ColumnSpan)" Value="1" />
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="Narrow">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="0" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="First.(Grid.Row)" Value="0" />
                    <Setter Target="First.(Grid.Column)" Value="0" />
                    <Setter Target="Second.(Grid.Row)" Value="1" />
                    <Setter Target="Second.(Grid.Column)" Value="0" />
                    <Setter Target="Third.(Grid.Row)" Value="2" />
                    <Setter Target="Third.(Grid.Column)" Value="0" />

                    <Setter Target="First.(Grid.ColumnSpan)" Value="3" />
                    <Setter Target="Second.(Grid.ColumnSpan)" Value="3" />
                    <Setter Target="Third.(Grid.ColumnSpan)" Value="3" />
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <ScrollViewer Grid.Row="1">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <StackPanel Name="First" Margin="20,20,0,0">
                <TextBlock TextWrapping="Wrap">
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
                    Cras id orci iaculis, aliquet nibh at, dictum lorem. Vivamus 
                    tempus tristique sollicitudin. Etiam interdum et lectus 
                    semper molestie. Phasellus lobortis felis quis risus posuere, 
                    id molestie mi sagittis. Cras odio leo, dictum vitae euismod et, 
                    lacinia non lectus. Integer quis massa velit. Ut at dui 
                    rutrum, venenatis dui a, pretium arcu. Nunc eu urna pulvinar, 
                    condimentum sapien non, consectetur turpis. Pellentesque dapibus, 
                    eros ac rutrum congue, quam dolor rhoncus nunc, ut sagittis nisl 
                    urna in ante. Sed nunc libero, aliquet at elit eget, vulputate 
                    ultrices leo. Aliquam vel sapien varius, blandit dui ac, 
                    fringilla metus. Lorem ipsum dolor sit amet, consectetur 
                    adipiscing elit. Fusce vehicula odio sit amet tortor lobortis 
                    sagittis. Nullam vestibulum tortor eget risus vulputate, at 
                    semper nunc pharetra. Nullam fringilla dapibus turpis non 
                    vehicula. Proin sollicitudin sapien enim, at interdum risus 
                    cursus quis.
                </TextBlock>
            </StackPanel>
            <StackPanel Name="Second" Grid.Row="1" Margin="20,20,0,0">
                <TextBlock TextWrapping="Wrap">
                    Nam sollicitudin justo quis consequat molestie. Etiam dictum 
                    sodales tellus, ut consectetur magna sodales in. Phasellus viverra 
                    volutpat porttitor. Pellentesque sed condimentum neque. In 
                    ultrices ex ac lacus tincidunt, eget euismod urna cursus. Donec tempor 
                    mauris leo, ac cursus nisl tempus a. Aliquam dignissim eleifend lorem a 
                    facilisis. Praesent tincidunt semper ante non ornare. Cras eleifend 
                    eros et tincidunt auctor. Duis lorem nunc, dictum dignissim est vitae, 
                    luctus dapibus lacus. Donec fringilla ipsum nec diam sagittis, 
                    nec suscipit metus maximus. Aliquam aliquam non ante tincidunt 
                    fringilla. Phasellus auctor, nisl non rutrum imperdiet, arcu
                    purus pretium libero, nec eleifend metus turpis vel ante. Phasellus 
                    sit amet rhoncus lectus.
                </TextBlock>
            </StackPanel>
            <StackPanel Name="Third" Grid.Row="2" Margin="20,20,0,0">
                <TextBlock TextWrapping="Wrap">
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
                    Cras id orci iaculis, aliquet nibh at, dictum lorem. Vivamus 
                    tempus tristique sollicitudin. Etiam interdum et lectus 
                    semper molestie. Phasellus lobortis felis quis risus posuere, 
                    id molestie mi sagittis. Cras odio leo, dictum vitae euismod et, 
                    lacinia non lectus. Integer quis massa velit. Ut at dui 
                    rutrum, venenatis dui a, pretium arcu. Nunc eu urna pulvinar, 
                    condimentum sapien non, consectetur turpis. Pellentesque dapibus, 
                    eros ac rutrum congue, quam dolor rhoncus nunc, ut sagittis nisl 
                    urna in ante. Sed nunc libero, aliquet at elit eget, vulputate 
                    ultrices leo. Aliquam vel sapien varius, blandit dui ac, 
                    fringilla metus. Lorem ipsum dolor sit amet, consectetur 
                    adipiscing elit. Fusce vehicula odio sit amet tortor lobortis 
                    sagittis. Nullam vestibulum tortor eget risus vulputate, at 
                    semper nunc pharetra. Nullam fringilla dapibus turpis non 
                    vehicula. Proin sollicitudin sapien enim, at interdum risus 
                    cursus quis.
                </TextBlock>
            </StackPanel>
        </Grid>
    </ScrollViewer>
</Grid>

当应用程序窗口的宽度小于650时,它将堆栈面板设置为低于另一个,因此您具有单列视图。当宽度大于650时,它将它们分成三列。

答案 3 :(得分:0)

我想的一种方法是创建一个循环,然后使用内联将其添加到文本块中,请查看以下示例:

    string teststring = "fdssssssfdsfdsfjhjkdhfjkdsjkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkfsdfdsfdscccxcxvdsfsfdsfsdf";

    private void button2_Click(object sender, RoutedEventArgs e)
    {
        for (int i = 0; i < teststring.Length; i += 10)
        {
            if ((i + 10) < teststring.Length)
            {
                textBlock.Inlines.Add(new Run { Text = Environment.NewLine + teststring.Substring(i, 10) });
            }
            else
            {
                textBlock.Inlines.Add(new Run { Text = Environment.NewLine +  teststring.Substring(i) });
            }
        }
    }