将文本 属性 设置为大字符串时 WPF 文本框元素冻结

WPF Textbox Element freezes when setting the text property to a large string

我目前正在开发一个 UWP 应用程序,我遇到了一个问题 TextBox WPF Element,在处理较大的文本时似乎性能很差。将剪贴板中的大文本粘贴到文本框中效果非常好,但是当我尝试以编程方式设置文本时,它会冻结整个应用程序:

textbox.Text = sb.ToString(); //Freezes or takes for ever

这就是我在 MainPage.xaml 中定义文本框的方式:

<TextBox x:Name="textbox" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" Margin="0,0,0,70"/>

有没有人知道这个性能问题的解决方案或者是 有我可以使用的替代文本字段元素吗?

好的......我已经能够得到添加文本所需的时间,最多需要 133 毫秒,这是我发现的最高时间。那是轻微的抖动;如果我添加 50K 个字符,大约需要 1000 毫秒,这很明显,但考虑到字符数,还算不错。

为了执行测试,我首先创建了一个视图: ProgressBar 检测 UI 冻结/抖动。 TextBlock 以毫秒为单位显示添加文本所需的时间。 Button 开始添加文本。 TextBox 将文本添加到。

MainPage.xaml

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

    <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

        <ProgressBar Name="progressBarAddingText"
                     IsIndeterminate="True" />

        <TextBlock Name="textBlockAddingTextTime" />

        <Button Content="Add Text"
                Click="ButtonClick" />

        <TextBox Name="textBoxAddingText"
                 HorizontalAlignment="Stretch"
                 VerticalAlignment="Stretch"
                 ScrollViewer.VerticalScrollBarVisibility="Auto"
                 TextWrapping="Wrap"
                 Margin="0,0,0,70" />

    </StackPanel>
</Page>

MainPage.xaml.cs

using System.Diagnostics;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml.Controls;

namespace Question_Answer_UWPApp
{
    public sealed partial class MainPage : Page
    {
        public static Stopwatch stopwatch = new Stopwatch();
        public MainPage()
        {
            InitializeComponent();
        }

        public async void AddTextAsynchronously()
        { 
            var text = await Task.Run(() =>
            {
                var stringBuilder = new StringBuilder();

                for (int i = 0; i < 5000; i++)
                    stringBuilder.Append("X");

                return stringBuilder.ToString();
            });

            stopwatch.Start();

            textBoxAddingText.Text = text;

            stopwatch.Stop();
            textBlockAddingTextTime.Text = $"{stopwatch.ElapsedMilliseconds.ToString()} milliseconds";
        }

        private void ButtonClick(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            AddTextAsynchronously();
        }
    }
}

在这个测试中,我得到了大约 133ms,但是当我将 StringBuilder 放在 Task 之外并使用 Task 只是为了构建 StringBuilder(本质上允许我要说 .Text = stringBuilder.ToString() 还需要大约 10 毫秒。这意味着 StringBuilder 不是瓶颈。我不认为将文本添加到 TextBox 是你的瓶颈要么。

通过这个测试,我觉得你应该在其他地方寻找你的瓶颈。这应该可以安全地回答通过代码向 TextBox 添加文本并不耗时的问题。