如何在 Windows Store 应用程序中显示大量文本?

Posted

技术标签:

【中文标题】如何在 Windows Store 应用程序中显示大量文本?【英文标题】:How to display large amounts of Text in a Windows Store application? 【发布时间】:2014-12-05 13:10:14 【问题描述】:

当在 WinRT 中的 RichTextBlock 甚至 TextBlock 中显示大量文本时,我注意到 WinRT XAML 呈现引擎已达到其极限。因此,请考虑以下简单示例,我在 XAML 中定义了 RichTextBlock,并在后面的代码中使用大量文本填充它。 (这对于一个简单的TextBlock 来说也是类似的。)

这是 XAML 部分:

<ScrollViewer>
    <RichTextBlock Name="rtb" />
</ScrollViewer>

后面还有一些代码来填充它:

void MainPage_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)

    string text = Enumerable.Range(0, 200).Aggregate("", (current, i) => current + loremipsum);
    text = text.Replace("\r\n", "\n").Replace("\r", "\n");
    foreach (var line in text.Split('\n'))
    
        var paragraph = new Paragraph();
        paragraph.Inlines.Add(new Run  Text = line );
        this.rtb.Blocks.Add(paragraph);
    


private const string loremipsum = @"
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. 
    Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. 
    Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. 
    Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 
    Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. ";

一开始这似乎可行,但是当您开始缩放时,应用程序将冻结并崩溃,因为 xaml 渲染器失败。对于没有任何交互的大量文本,这种情况会立即发生。

所以问题是:如何在 WinRT 中显示大量文本,其中大意味着大约 100 KB 的文本,甚至更多到 5 MB?

注意:我还没有尝试过 WebBrowser 控件,因为它应该是只读的并且我想避免复制和粘贴。所以 WebBrowser 控件不是我的选择。

编辑

我找到了一个临时解决方案,我将这些行作为项目添加到 ItemsControl,其中项目被虚拟化。

<ItemsControl Name="ItemsControl">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.Template>
        <ControlTemplate TargetType="ItemsControl">
            <ScrollViewer>
                <ItemsPresenter/>
            </ScrollViewer>
        </ControlTemplate>
    </ItemsControl.Template>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="Binding"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

使用此解决方案,应用不再崩溃,但确实缺乏性能。

【问题讨论】:

我会检查以确保您使用的是支持incremental loading 的支持项目集合。您还可以分阶段加载文本,以便即使文本没有立即出现,它仍然具有高性能和响应性,类似于图像处理。另外,您是否不断地从磁盘读取文本?如果是这样,一开始就将其全部加载到内存中可能会有所帮助。你也可以阅读this。也许试试ItemsStackPanel 我会将您的方法与虚拟化结合使用,并将您的文本分成几部分。 【参考方案1】:

为 Win2D 做好准备。以下工作非常顺利:

public class InifiniteTextBlock : Grid

    CanvasControl canvasControl;

    public InifiniteTextBlock()
    
       Initialize();
    

    private const string loremipsum = @"
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. 
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. 
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. 
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, velillum dolore eu feugiat nulla facilisis. ";

    private string largeloremipsum;

    private async void Initialize()
    
        canvasControl = new CanvasControl()  ClearColor = Colors.Transparent, Width = 480, Height = 4000 ;
        largeloremipsum = String.Concat(loremipsum, loremipsum, loremipsum, loremipsum, loremipsum);
        this.Children.Insert(0, canvasControl);
        while (!canvasControl.ReadyToDraw)
        
            await Task.Delay(60);
        

        canvasControl.Draw += (s, e) =>
        
            var test = new CanvasTextFormat();
            e.DrawingSession.DrawText(largeloremipsum, new Rect(0,0,480,4000), Colors.Black, test);
        ;
        canvasControl.Invalidate();
    

然后在 XAML 中执行以下操作:

<ScrollViewer>
  <local:InifiniteTextBlock/>
</ScrollViewer>

而且像魅力一样工作!

【讨论】:

文本显示快速但不滚动。如图所示的代码不起作用。 Win2D 需要一个 NUGET 包。就像速度一样,可惜它实际上不起作用。

以上是关于如何在 Windows Store 应用程序中显示大量文本?的主要内容,如果未能解决你的问题,请参考以下文章

乘风破浪,如何查看Windows 11商店应用的安装目录,面向微软商店(Microsoft Store)开发发力

Windows Store App XAML:Gridview 不全屏显示图像

如何在 windows store 8.1 MVVM 应用程序中添加命令行为

Windows10 系统安装微软商店(ms-windows-store)

从 Windows Store App 中的目标应用程序回调共享应用程序

登录后如何在Windows-Start-Up上自动运行第三方Windows 10 Store App