我有一个UserControl
包含一个TextBox
.当我的主窗口加载时,我想将焦点设置到此文本框,所以我添加Focusable="True" GotFocus="UC_GotFocus"
到UserControl
s定义和FocusManager.FocusedElement="{Binding ElementName=login}"
我的主窗口定义.在UC_GotFocus
方法中,我只是调用.Focus()
我想要关注的控件,但这不起作用.
我需要做的就是在应用程序启动时有TextBox
一个UserControl
接收焦点.
任何帮助将不胜感激,谢谢.
我最近修复了这个问题,因为登录初始屏幕是在首次加载主窗口时通过故事板显示的.
我相信修复有两个关键.一个是使包含元素成为焦点范围.另一个是处理由加载窗口触发的故事板的Storyboard Completed事件.
此故事板使用户名和密码画布可见,然后淡入100%不透明.关键是在故事板运行之前,用户名控件是不可见的,因此该控件在可见之前无法获得键盘焦点.让我离开一段时间的是它有"焦点"(即焦点是真的,但事实证明这只是逻辑焦点)并且我不知道WPF在阅读Kent Boogaart之前有逻辑和键盘焦点的概念回答并查看Microsoft的WPF 链接文本
一旦我这样做,我的特定问题的解决方案是直截了当的:
1)使包含元素成为焦点范围
2)将完成的事件处理程序附加到故事板
...
和
3)设置我的用户名TextBox,使键盘焦点在storyboard完成的事件处理程序中.
void UserNamePassword_Storyboard_Completed(object sender, EventArgs e) { m_uxUsername.Focus(); }
请注意,调用item.Focus()会导致调用Keyboard.Focus(this),因此您无需显式调用它.看到这个关于Keyboard.Focus(item)和item.Focus之间区别的问题.
它的愚蠢,但它的工作原理:
弹出等待一段时间的线程然后返回并设置您想要的焦点.它甚至可以在元素主机的上下文中工作.
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e) { System.Threading.ThreadPool.QueueUserWorkItem( (a) => { System.Threading.Thread.Sleep(100); someUiElementThatWantsFocus.Dispatcher.Invoke( new Action(() => { someUiElementThatWantsFocus.Focus(); })); } ); }
就在最近,我有一个包含一些TextBlocks的列表框.我希望能够双击文本块并将其转换为TextBox,然后专注于它并选择所有文本,以便用户可以开始键入新名称(类似于Adobe图层)
无论如何,我正在做一个事件,它只是没有工作.我这里的神奇子弹是确保我将事件设置为处理.我认为它是设置焦点,但是一旦事件沿着路径向下切换逻辑焦点.
这个故事的寓意是,确保你把事件标记为已处理,这可能是你的问题.
"在应用程序启动时设置初始焦点时,接收焦点的元素必须连接到PresentationSource,并且元素必须将Focusable和IsVisible设置为true.建议初始焦点的建议位置是"已加载的事件处理程序"(MSDN)
只需在Window(或Control)的构造函数中添加一个"Loaded"事件处理程序,并在该事件处理程序中调用目标控件上的Focus()方法.
public MyWindow() { InitializeComponent(); this.Loaded += new RoutedEventHandler(MyWindow_Loaded); } void MyWindow_Loaded(object sender, RoutedEventArgs e) { textBox.Focus(); }
因为我尝试了一个fuzquat的解决方案,并发现它是最通用的,我想我会分享一个不同的版本,因为一些人抱怨它看起来很乱.所以这里是:
casted.Dispatcher.BeginInvoke(new Action(x => { x.Focus(); }), DispatcherPriority.ApplicationIdle, casted);
没有Thread.Sleep,没有ThreadPool.我希望足够清洁.真的可以使用一些代表,所以我可以评论其他人的解决方案.
更新:
因为人们似乎喜欢漂亮的代码:
public static class WpfExtensions { public static void BeginInvoke(this T element, Action action, DispatcherPriority priority = DispatcherPriority.ApplicationIdle) where T : UIElement { element.Dispatcher.BeginInvoke(priority, action); } }
现在你可以像这样调用它:
child.BeginInvoke(d => d.Focus());