基本上我的问题是,如果用户编辑了内容,当我尝试以编程方式将超过 2 个链接应用到 ITextDocument 时,我会收到 AccessViolationException。我已经基于 windows phone (8.1) Blank App 模板制作了一个简单的演示应用程序。
我添加到主页:
<StackPanel Margin="19,0,0,0">
<Button
Content="Apply Links"
Click="Button_Click"
/>
<RichEditBox
x:Name="RtfBox"
Height="300"
Loaded="RtfBox_Loaded"
Margin="0,0,19,0"
TextWrapping="Wrap"
/>
</StackPanel>
对于我添加的同一页面背后的代码(使用不包括的语句):
private void RtfBox_Loaded(object sender, RoutedEventArgs e)
{
//RtfBox.Document.SetText(TextSetOptions.None, "Links to demo, example, test. More links to demo, demo, example, test and test.");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var pages = new Dictionary<Guid, string> { { Guid.NewGuid(), "demo" }, { Guid.NewGuid(), "example" }, { Guid.NewGuid(), "test" } };
// NOTE: Avoid performance implications of many small updates
RtfBox.Document.BatchDisplayUpdates();
ITextRange range;
foreach (var page in pages)
{
var link = string.Format("\"richtea.demo://pages/{0}\"", page.Key);
var skip = 0;
while ((range = RtfBox.Document.GetRange(skip, TextConstants.MaxUnitCount)).FindText(page.Value, TextConstants.MaxUnitCount, FindOptions.None) != 0)
{
if (range.Link == "")
{
// TODO: Stop this throw exceptions
System.Diagnostics.Debug.WriteLine("Setting text at position {0} to link: '{1}'.", range.StartPosition, link);
range.Link = link;
}
skip = range.EndPosition;
}
}
RtfBox.Document.ApplyDisplayUpdates();
}
如果您启动它并键入“演示页面的链接”之类的内容并单击按钮,它就会正确地变成一个链接。您可以继续放置相同的文本并单击按钮,它会继续工作。
但是,如果您输入三个或更多(出于某种原因,对我来说总是 3 个或更多)单词demo、example或test(我的关键字)并点击按钮,它会在AccessViolationException
on setting 上出错range.Link = link
。值得注意的是,如果您在调试时检查,range.Link 属性实际上已设置。
更有趣的是,如果您取消注释RtfBox_Loaded
的内容,并运行应用程序并立即单击按钮,它会处理得很好。所以它似乎与在 RichEditBox 上设置的选择有关?我尝试在应用链接之前禁用控件,但这对我没有帮助。
其他一些让我更难在这里诊断问题的因素包括:
- 如果我逐行调试,它似乎更频繁地工作,所以也可能与时间有关
- 我似乎不能在 UI 线程上使用 ITextDocument(COM 对象无法转换),所以虽然异步似乎是一种更好的方法,但我在这里没有成功。
另外为了记录,我尝试批量进行所有更新而不是用户键入它们的原因是我不想在重命名或删除笔记时处理清理,我不想真的希望在编辑时或保存这些链接,但我可以接受后者。