Paragraph.BringIntoView()仅在聚焦时起作用

时间:2009-10-23 15:51:33

标签: c# wpf focus paragraph

我正在开发一个基于RichEditBox的文本编辑器。我已经实现了“Go to line”功能,最终解析为 TextPointer.Paragraph.BringIntoView();

除此之外,我还设置了插入位置。 我发现BringIntoView仅在我首先点击RichEditBox时才会有效(对焦)。否则它似乎被忽略了。我可以看到插入位置已经被BringIntoView周围的代码调整过了。

有谁知道这个问题的原因/性质是什么?我怎样才能克服它?

2 个答案:

答案 0 :(得分:1)

找到了一个解决方法,不确定它是否可以在纯WPF环境中工作,在我的情况下,我在主要的Windows窗体解决方案中使用WPF UserControls在需要的地方运行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计时器就像一个魅力。

答案 1 :(得分:0)

首先,您是否可以先使用RichTextBoxKeyboard.Focus(richTextBox)提供richTextBox.Focus()(?)焦点?