关闭

FocusScope学习三: 对FocusScope 的探究与总结

1419人阅读 评论(0) 收藏 举报

http://social.msdn.microsoft.com/forums/en-US/wpf/thread/f5de6ffc-fa03-4f08-87e9-77bbad752033/

这个帖子很好的讨论了Focus Scope的种种,WeiFen 和John给出了我最接受的总结: 我在最后也给出了我的总结:

From WeiFen:

I think I can explain this after digging into the framework source code.

1. After clicking, the MenuBase and ButtonBase class will try to restore keyboard focus to previous focused element by calling Keyboard.Focus(null). This will set keyboard focus to top level main window. Since Window is a FocusScope, this will set focus to main window's FocusedElement. Normally we don't expect a click will change the focus, that's where the confusion come from. But this behavior makes sense:

1) MenuBase works in a open-dismiss way. It should not have the focus after clicking. Actually I think they should not get focus at all, like in Win32 or Win forms. But this is another topic.

2) Normally after clicking a button, we're not likely to click it again. So it's naturaly to restore the focus to previously focused element.

我并没有在MSDN上查到Keyboard.Focus(null)的功能,不过既然他看了WPF源代码了,那么应噶是没错。不过假如把Window的IsFocusScope设置成false,不知道会怎么样

2. The nested FocusScope. It's not actually that complex as we expected. Whenever an UIElement receives keyboard focus, it will find its DIRECT parent focus scope, and set this focus scope's FocusedElement to itself. Keyboard focus leaves the focus scope will do nothing.

恩,和学习二里面相互印证(准确来说,学习二的作者读的也是WeiFeng的总结) 

Consider the check box sample you provided:

1) If you set IsFocusScope="true" on StackPanel, focus the check box will set StackPanel's FocusedElement to check box, and main window's FocusedElement remains unchanged - ListViewItem; After clicking the check box, because of Keyboard.Focus(null) called, the keyboard focus will set to previous ListViewItem.

2) If you remove IsFocusScope="true" on StackPanel, focus the check box will set main window's FocusedElement to the check box. Keyboard.Focus(null) will set the focus back to the check box.

If you want both IsFocusScope="true" and no keyboard focus change after clicking the check box, add the following code to your window class (of course you need to add x:Name="checkBox" in the XAML file):

假如Window没有Focused Element,那么焦点则不会转移。


protected
 override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)

{

base.OnGotKeyboardFocus(e);

if (e.Source == checkBox)

FocusManager.SetFocusedElement(this, checkBox);

}

 

Hope this helps,

- Weifen

From John:

Wow long discussion on this...  I had to figure some of this out early on, and I thought I chip in with what I discovered.  I found some errors in the documentation that I don't think have been corrected.

Based on my testing the correct explanation of command routing when no target is set is:

The element within the Windows focus scope that has logical focus will be used as the command target.

Note that it's the windows focus scope not the active focus scope.  And it's logical focus not keyboard focus.

When it comes to command routing, FocusScopes remove any item you place them on and it's child elements from the command routing path.  

So if you create a focus scope in your app and want a command to route in to it you will  have to set the command target manually.

Or, you can not use FocusScopes other than for toolbars, menus etc and handle the container focus problem manually.

The above is pretty much covered in the posts above, but I think this states it a little clearer.  If not... sorry for butting in.<g>

HTH


John Fenton


From Me:


我的测试是基于WPF4,好像他们改进了下,一下是我的总结:

1)假如CommandSource在一个FocusScope里面,命令被触发,那么WPF会先寻找该FocusScope的事件处理程序(CommandBindings),如果有,则使用这个。我测试的是CommandBinding正好是CommandSource的Parent Container,所以不确定是不是该FocusScope的CommandBindings还是Parent Container的CommandBindings。
2)假如主窗口有Focus Element,那么就会使用该Focus Element的Built-in的事件处理程序,假如没有,那么就是用主窗口的。假如还是没有,会找到你的FocusScope和主窗口之间的CommandBindings(直线路上,就是ParentContainer, Parent-Parent Container的,而不会找Sibling的)但是只会找CommandBindings,不会找到那些Built-in的事件处理程序。

其实也不必太在意,真正写代码不会那么复杂的!另外 Pro WPF in C# 2010里面也讲的比较透彻,并给出了一个例子。


0
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:824256次
    • 积分:8029
    • 等级:
    • 排名:第2511名
    • 原创:121篇
    • 转载:73篇
    • 译文:0篇
    • 评论:87条
    最新评论