我正在开发一个C#/ Xaml UWP文本编辑应用程序,该应用程序使用RichEditBox控件来编辑文本文件。但是,我注意到当我加载较大的文件(~1mb及以上,甚至更少)时,控件在几个关键区域中挣扎:1)加载文件的内容需要一段时间,2)一旦加载最后,滚动非常生涩,输入文件既不平滑也不敏感。
我遇到的最接近的答案是this(它所描述的正是我遇到的问题)但它似乎不适用于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.14mb文本文件。加载需要一些时间,虽然滚动条高度表明它已加载所有内容,但它实际上不会显示从行2098开始的任何文本(总共有3,771行);即使在后续重新加载时,它也会始终停在此线上。
见图:
您还可以看到可见的最后一行被其上面的行混淆。
作为参考,我可以从这里下载我遇到问题的文件(但要清楚这是一个类似大小的所有文本文件的问题,甚至可能更少):http://mtrostyle.net/appytext/testfile.txt。
答案 0 :(得分:0)
是的,当我加载你提供的txt文件时,我得到了同样的结果。我一直在向相关团队报告此问题。目前,显示该文件的一种解决方法是在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);
}