【发布时间】:2015-07-07 15:18:44
【问题描述】:
这是一个奇怪的问题,我什至不知道要搜索什么,但相信我,我知道。
我有一个文本框并绑定到它的OnTextChanged 事件是下面的方法。
这里的目的是给文本框焦点,将光标移动到文本框的末尾,然后将焦点返回到实际焦点所在的位置(通常是按钮)。问题是在我将焦点发送回最初聚焦的元素之前,似乎 TextBox 没有“重绘”(因为没有更好的词?),因此光标位置不会在屏幕上更新(尽管所有属性都认为它有) .
目前,我已经粗暴地破解了这个,基本上将前一个焦点项目的重新聚焦延迟了 10 毫秒,并在不同的线程中运行它,以便 UI 有时间更新。现在,这显然是一个任意的时间量,并且在我的机器上运行良好,但是在旧机器上运行这个应用程序的人可能会遇到问题。
有没有合适的方法来做到这一点?我想不通。
private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e)
{
if (sender == null) return;
var box = sender as TextBox;
if (!box.IsFocused)
{
var oldFocus = FocusManager.GetFocusedElement(FocusManager.GetFocusScope(this));
box.Select(box.Text.Length, 0);
Keyboard.Focus(box); // or box.Focus(); both have the same results
var thread = new Thread(new ThreadStart(delegate
{
Thread.Sleep(10);
Dispatcher.Invoke(new Action(() => oldFocus.Focus()));
}));
thread.Start();
}
}
编辑
我的一个新想法是在 UI 完成更新后运行 oldFocus.Focus() 方法,所以我尝试了以下方法,但得到了相同的结果:(
var oldFocus = FocusManager.GetFocusedElement(FocusManager.GetFocusScope(this));
Dispatcher.Invoke(DispatcherPriority.Send, new Action(delegate
{
box.Select(box.Text.Length, 0);
box.Focus();
}));
Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action(() => oldFocus.Focus()));
【问题讨论】:
-
我猜这是一个 WPF 应用程序,所以我更改了标签。您通常应该告诉我们您正在编写什么样的应用程序,这样我们就不必猜错了。
-
我很抱歉。以后不会忘记的。
-
你试过 oldFocus.Invalidate() 来强制重绘吗?
-
“光标”是指插入符号吗?
-
@JasonTyler 我试过 box.InvalidateVisual();没有变化。似乎我无法弄清楚如何强制 UI 重绘框。不确定这是否是正确的术语。