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

转载 2012年03月28日 22:15:52

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里面也讲的比较透彻,并给出了一个例子。


FocusScope学习二: 很好的理解FocusScope的工作原理

http://www.codeproject.com/Articles/38507/Using-the-WPF-FocusScope Introduction Often, it is...
  • puncha
  • puncha
  • 2012年03月28日 21:58
  • 2604

QML QuickItem鼠标键盘处理

使用QML和C++混合编程,要处理键盘事件,和鼠标事件一样,也是个麻烦事。 键盘事件与鼠标事件的一大不同是,鼠标事件是有坐标的,而键盘事件没有坐标,所以处理鼠标事件的前提是控件获得了焦点(focus...
  • LaineGates
  • LaineGates
  • 2016年03月31日 15:22
  • 1134

MyBatis学习总结(三)——优化MyBatis配置文件中的配置

一、连接数据库的配置单独放在一个properties文件中   之前,我们是直接将数据库的连接配置信息写在了MyBatis的conf.xml文件中,如下: 1 xml version="...
  • qq_27376871
  • qq_27376871
  • 2016年05月16日 16:26
  • 1170

七步从Angular.JS菜鸟到专家(2):Scopes(1)

 这是"AngularJS - 七步从菜鸟到专家"系列的第二篇。 在第一篇我们展示了如何开始搭建一个Angular应用。在这一篇里,我们要讨论一个理解AngularJS运作原理所必须的基本概念...
  • u013510614
  • u013510614
  • 2014年08月17日 18:52
  • 678

angular学习(五)—— Scopes

来源地址:http://blog.csdn.net/lastsweetop/article/details/51833370 Scopes简介 Scopes是一个指向application...
  • Servenity
  • Servenity
  • 2017年03月20日 13:18
  • 125

Nature:Hinton、LeCun、Bengio三巨头权威科普深度学习

Hinton、LeCun、Bengio 是深度学习的最权威的科学家。文中介绍的网络是深度学习中最为成熟,经典的部分。读这篇文章可以对深度学习的核心模块有一个最快的认识。    背景 ...
  • Richard_More
  • Richard_More
  • 2016年08月27日 12:00
  • 2523

angularjs学习心得

angularjs使用的一些心得,$mdDialog的使用问题
  • liufang1991
  • liufang1991
  • 2016年10月10日 17:36
  • 891

计算机网络探究(二)TCP的连接和终止

转自:http://www.blogjava.net/jasmine214--love/archive/2010/12/15/340680.html?opt=admin TCP是一个面向连接...
  • DADADIE
  • DADADIE
  • 2016年08月12日 18:45
  • 731

UI自动测试中遇到

在火狐或IE上可以正常运行,但是在Chrome则报错: 表单源代码如: 解决: from selenium import webdriver from time import sleep from...
  • JOJOY_tester
  • JOJOY_tester
  • 2017年06月03日 10:42
  • 1078

angular2学习使用心得

angular2的学习笔记
  • liufang1991
  • liufang1991
  • 2017年07月25日 09:37
  • 713
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:FocusScope学习三: 对FocusScope 的探究与总结
举报原因:
原因补充:

(最多只允许输入30个字)