我正在开发基于 RichEditBox 的文本编辑器。我已经实现了功能“Go to line”,最终解决为
TextPointer.Paragraph.BringIntoView();
与此同时,我还设置了插入符号的位置。我发现BringIntoView
只有当我点击第RichEditBox
一个(聚焦它)时才有效。否则它似乎被忽略了。我可以看到插入符号的位置已经被 BringIntoView 周围的代码调整了。
有人知道这个问题的原因/性质是什么吗?我怎样才能克服它?
找到了一个解决方法,不确定它是否可以在纯 WPF 环境中工作,在我的情况下,我在需要时使用 WPF UserControls 在主要是 Windows 窗体解决方案中运行 WPF。
不要立即调用 BringIntoFocus(),而是通过将其添加到由计时器处理的队列中来推迟它。例如:
System.Windows.Forms.Timer DeferredActionTimer = new System.Windows.Forms.Timer() { Interval = 200 };
Queue<Action> DeferredActions = new Queue<Action>();
void DeferredActionTimer_Tick(object sender, EventArgs e) {
while(DeferredActions.Count > 0) {
Action act = DeferredActions.Dequeue();
act();
}
}
在您的表单构造函数中,或在 OnLoad 事件中添加:
DeferredActionTimer.Tick += new EventHandler(DeferredActionTimer_Tick);
DeferredActionTimer.Enabled = true;
最后,不要TextPointer.Paragraph.BringIntoView();
直接调用,而是这样调用:
DeferredActions.Enqueue(() => TextPointer.Paragraph.BringIntoView());
请注意,Windows 窗体计时器在主线程中启动事件(通过消息泵循环)。如果您必须使用另一个计时器,则需要一些额外的代码。我建议您使用System.Timers.Timer
而不是System.Threading.Timer
(它更线程安全)。您还必须将操作包装在Dispatcher.Invoke
结构中。就我而言,WinForms 计时器就像一个魅力。
你不能先给RichTextBox
(?) 焦点,然后使用Keyboard.Focus(richTextBox)
orrichTextBox.Focus()
吗?