c# - WPF TextBox 移动光标和改变焦点

标签 c# .net wpf mvvm textbox

这很奇怪,我什至不知道要搜索什么,但相信我,我知道了。

我有一个文本框并绑定(bind)到它的 OnTextChanged 事件是下面的方法。

此处的目的是为文本框提供焦点,将光标移动到 TextBox 的末尾并将焦点返回到实际焦点(通常是按钮)。问题是,在我将焦点发送回最初聚焦的元素之前,似乎 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()));

最佳答案

你在正确的轨道上,问题是你的 .Focus()调用坚持,您需要在调度程序中将调用延迟到稍后时间。
而不是使用 DispatcherPriority Send 的值(最高),请尝试使用 Dispatcher 将焦点设置在稍后的 DispatcherPriority,例如 Input

Dispatcher.BeginInvoke(DispatcherPriority.Input,
new Action(delegate() { 
    oldFocus.Focus();         // Set Logical Focus
    Keyboard.Focus(oldFocus); // Set Keyboard Focus
 }));

如您所见,我还设置了键盘焦点。
WPF 可以有多个焦点范围,一个以上的元素可以有逻辑焦点 (IsFocused = true)。但是,只有一个元素可以拥有键盘焦点并接收键盘输入。

关于c# - WPF TextBox 移动光标和改变焦点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13995489/

相关文章:

c# - 非泛型类型的协变/逆变支持吗?

c# - 将 Entity Framework 模型映射到多个表

c# - .NET Core 中 Assembly.GetEntryAssembly() 的等价物是什么?

c# - .xaml.cs 文件中的 "Go To Definition"将我带到 .g.i.cs 文件而不是 Visual Studio 2015 中的 .xaml 文件

WPF圆形奇怪的边框

c# - Creators Update 后在 OnCollectionChanged 上获取线程访问异常

c# - 错误 : Cannot obtain Metadata; using WCF Test client, C#,并尝试实现 webhttpbinding 和 json

c# - 为特定的 GDI 设备上下文禁用抗锯齿

c# - 在哪里存储桌面应用程序的用户数据?

c# - 如何从事件中删除所有事件处理程序