Производительность RichEditBox снижается при работе с большими текстовыми файлами (загрузка + прокрутка)

Я занимаюсь разработкой приложения для редактирования текста на C#/Xaml UWP, которое использует элемент управления RichEditBox для редактирования текстовых файлов. Тем не менее, я заметил, когда я загружаю большие файлы (~1 МБ и выше, возможно, даже меньше), что элемент управления борется в нескольких ключевых областях: 1) требуется некоторое время для загрузки содержимого файла и 2) как только он наконец, прокрутка очень резкая, и ввод в файл не является ни плавным, ни отзывчивым.

Самый близкий ответ, с которым я столкнулся, заключается в следующем (то, что он описывает, это как раз та проблема, с которой я столкнулся), но, похоже, он не применим к приложению UWP.

РЕДАКТИРОВАТЬ:

Когда я открываю файл, стоит отметить следующий код:

_currentFile.Content = await readFile(file);
_currentFile._richeditbox.Document.SetText(TextSetOptions.None, _currentFile.Content);

Это функция readFile(), которая помогла через https://social.msdn.microsoft.com/Forums/sqlserver/en-US/0f3cd056-a2e3-411b-8e8a-d2109255359a/uwpc-reading-ansi-text-file?forum=wpdevelop:

private async Task<string> readFile(StorageFile file)
{
    string charSet = null;

    try
    {
        await Task.Run(() =>
         {
             try
             {
                 using (FileStream fs = System.IO.File.OpenRead(file.Path))
                 {
                     Ude.CharsetDetector cdet = new Ude.CharsetDetector();
                     cdet.Feed(fs);
                     cdet.DataEnd();
                     charSet = cdet.Charset;
                 }
             }
             catch (Exception ex)
             {

             }
         });
    }
    catch (Exception e)
    {

    }

    Classes.File._lastEncoding = charSet;

    IBuffer buffer = await FileIO.ReadBufferAsync(file);
    DataReader reader = DataReader.FromBuffer(buffer);
    byte[] fileContent = new byte[reader.UnconsumedBufferLength];
    reader.ReadBytes(fileContent);
    string content = "";
    if (charSet == "windows-1252")
    {
        content = Encoding.GetEncoding("iso-8859-1").GetString(fileContent, 0, fileContent.Length);
    }
    else if (charSet == "UTF-16LE")
    {
        content = Encoding.Unicode.GetString(fileContent, 0, fileContent.Length);
    }
    else if (charSet == "UTF-16BE")
    {
        content = Encoding.BigEndianUnicode.GetString(fileContent, 0, fileContent.Length);
    }
    else
    {
        content = Encoding.UTF8.GetString(fileContent, 0, fileContent.Length);
    }

    return content;
} 

При отладке нет абсолютно никакой задержки при вызове функции readFile(); это выполняется очень быстро.

Я попытался загрузить текстовый файл 1.14 МБ. Загрузка занимает некоторое время, и когда это происходит, хотя высота полосы прокрутки указывает на то, что она полностью загружена, она фактически не отображает никакого текста, начиная со строки 2098 и далее (всего 3771 строка); он останавливается на этой линии последовательно даже при последующих перезагрузках.

Смотрите картинку:

Как вы также можете видеть, последняя видимая строка растирается со строкой над ней.

Для справки: файл, с которым у меня возникли проблемы, можно скачать отсюда (но, чтобы было ясно, это проблема со всеми текстовыми файлами одинакового размера, и, возможно, намного менее ровными): http://mtrostyle.net/appytext/testfile.txt.

1 ответ

Да, я получаю тот же результат на моей стороне, когда я загружаю предоставленный вами текстовый файл. Я сообщал об этой проблеме в соответствующую команду. В настоящее время одним из способов показать файл является отображение текста в WebView контроль. И набор импорта и экспорта для WebView, Для более вы можете обратиться к WebView,

<body>
    <textarea id="input" style="width:100%; height:400px;"></textarea>
    <script type="text/javascript">
        function SetText(text) {
            document.getElementById('input').textContent = text;
        }
        function SaveText() {
            var note = document.getElementById('input').textContent;
            window.external.notify(note);
        }
    </script>
</body>

MainPage.xaml

  <WebView x:Name="MyWebView" Source="ms-appx-web:///HomePage.html" Height="400" />

MainPage.xaml.cs

public MainPage()
{
    this.InitializeComponent();
    MyWebView.ScriptNotify += MyWebView_ScriptNotify;
}

private void MyWebView_ScriptNotify(object sender, NotifyEventArgs e)
{
    var saveText = e.Value.ToString();
}

private async void Button_Click(object sender, RoutedEventArgs e)
{
    Windows.Storage.Pickers.FileOpenPicker open =
            new Windows.Storage.Pickers.FileOpenPicker();
    open.SuggestedStartLocation =
        Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary;
    open.FileTypeFilter.Add(".rtf");
    open.FileTypeFilter.Add(".txt");

    Windows.Storage.StorageFile file = await open.PickSingleFileAsync();

  if (file != null)
   {
     var Content = await readFile(file);
     string[] args = { Content };
     await MyWebView.InvokeScriptAsync("SetText", args);
   } 

}

private async Task<string> readFile(StorageFile file)
{
    string charSet = null;

    try
    {
        await Task.Run(async () =>
        {
            try
            {
                using (var fs = await file.OpenAsync(FileAccessMode.Read))
                {
                    var tem = fs.AsStream();
                    Ude.CharsetDetector cdet = new Ude.CharsetDetector();
                    cdet.Feed(tem);
                    cdet.DataEnd();
                    charSet = cdet.Charset;
                }
            }
            catch (Exception ex)
            {
            }
        });
    }
    catch (Exception e)
    {
    }

    IBuffer buffer = await FileIO.ReadBufferAsync(file);
    DataReader reader = DataReader.FromBuffer(buffer);
    byte[] fileContent = new byte[reader.UnconsumedBufferLength];
    reader.ReadBytes(fileContent);
    string content = "";
    if (charSet == "windows-1252")
    {
        content = Encoding.GetEncoding("iso-8859-1").GetString(fileContent, 0, fileContent.Length);
    }
    else if (charSet == "UTF-16LE")
    {
        content = Encoding.Unicode.GetString(fileContent, 0, fileContent.Length);
    }
    else if (charSet == "UTF-16BE")
    {
        content = Encoding.BigEndianUnicode.GetString(fileContent, 0, fileContent.Length);
    }
    else
    {
        content = Encoding.UTF8.GetString(fileContent, 0, fileContent.Length);
    }

    return content;
}

private async void Button_Click_1(object sender, RoutedEventArgs e)
{
    await MyWebView.InvokeScriptAsync("SaveText", null);
}
Другие вопросы по тегам