似乎当WPF应用程序启动时,没有任何焦点.
这真的很奇怪.我使用的每个其他框架都符合您的期望:将初始焦点放在Tab键顺序中的第一个控件上.但我已经确认它是WPF,而不仅仅是我的应用程序 - 如果我创建一个新窗口,只是在其中放置一个TextBox,并运行应用程序,TextBox没有焦点,直到我点击它或按Tab键.呸.
我的实际应用程序比TextBox更复杂.我在UserControls中有几层UserControl.其中一个UserControls有Focusable ="True"和KeyDown/KeyUp处理程序,我希望它在我的窗口打开后立即获得焦点.不过,我仍然是一个WPF新手,而且我没有太多运气搞清楚如何做到这一点.
如果我启动我的应用程序并按Tab键,则焦点转到我的可聚焦控件,它开始以我想要的方式工作.但我不希望我的用户在开始使用窗口之前必须点击Tab.
我已经使用了FocusManager.FocusedElement,但是我不确定将它设置为哪个控件(顶级窗口?包含可聚焦控件的父级?可聚焦控件本身?)或者设置它的内容.
在窗口打开后,我需要做什么才能使我的深层嵌套控件具有初始焦点?或者更好的是,将第一个可聚焦控件聚焦在Tab键顺序中?
我有一个聪明的主意,就是通过Reflector来查看Focusable属性的使用位置,并找到了解决这个问题的方法.我只需要将以下代码添加到我的Window的构造函数中:
Loaded += (sender, e) => MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
这将自动选择Tab键顺序中的第一个控件,因此它是一个通用的解决方案,应该可以放入任何窗口和Just Work.
这也有效:
...
基于作为附加行为实现的已接受答案:
using System.Windows; using System.Windows.Controls; using System.Windows.Input; namespace UI.Behaviors { public static class FocusBehavior { public static readonly DependencyProperty FocusFirstProperty = DependencyProperty.RegisterAttached( "FocusFirst", typeof(bool), typeof(FocusBehavior), new PropertyMetadata(false, OnFocusFirstPropertyChanged)); public static bool GetFocusFirst(Control control) { return (bool)control.GetValue(FocusFirstProperty); } public static void SetFocusFirst (Control control, bool value) { control.SetValue(FocusFirstProperty, value); } static void OnFocusFirstPropertyChanged( DependencyObject obj, DependencyPropertyChangedEventArgs args) { Control control = obj as Control; if (control == null || !(args.NewValue is bool)) { return; } if ((bool)args.NewValue) { control.Loaded += (sender, e) => control.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); } } } }
像这样使用它:
我找到了另一种可能的解 Mark Smith发布了一个FirstFocusedElement标记扩展,用于与FocusManager.FocusedElement一起使用.
在进行了"WPF初始焦点噩梦"并基于堆栈上的一些答案后,以下证明我是最佳解决方案.
首先,添加您的App.xaml OnStartup()以下内容:
EventManager.RegisterClassHandler(typeof(Window), Window.LoadedEvent, new RoutedEventHandler(WindowLoaded));
然后在App.xaml中添加'WindowLoaded'事件:
void WindowLoaded(object sender, RoutedEventArgs e) { var window = e.Source as Window; System.Threading.Thread.Sleep(100); window.Dispatcher.Invoke( new Action(() => { window.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); })); }
必须使用线程问题,因为WPF的初始焦点主要是由于某些框架竞争条件而失败.
我发现以下解决方案最好,因为它在整个应用程序中全局使用.
希望能帮助到你...
奥兰
有同样的问题用简单的解决方案解决了它:在主窗口中:
在用户控件中:
private void UserControl_GotFocus_1(object sender, RoutedEventArgs e) { targetcontrol.Focus(); this.GotFocus -= UserControl_GotFocus_1; // to set focus only once }
您可以轻松地将控件设置为XAML中的焦点元素.
...
我从来没有尝试在用户控件中设置它,看看它是否有效,但它可能.