现在的位置: 首页 > 综合 > 正文

WPF 关于TreeView以及ContextMenu的种种

2012年10月02日 ⁄ 综合 ⁄ 共 2615字 ⁄ 字号 评论关闭

    这几天遇到一个Bug,这个Bug到现在还没有完美的解决,不过对WPF有了不少了解。为了防止忘记已经了解到的东西,我将查找到的所有知识和信息的网页都保留为打开状态。不能总是开几十个网页,所以临时将有价值的信息汇总,记成此文,稍后将进行整理。发现Google的时候中文找不到,一定记着用英文,英文往往能找到需要的信息。

    1. TreeView表示WPF的树状结构,若想让treeView的子项都包含某属性,可以用ItemContainerStyle,可以统一定义TreeViewItem的样式,通过应用HierarchicalDataTemplate。例如可以在其中定义一个DockPanel容器,然后里面放入若干textBlock,并可以为DockPanel定义右键菜单,及ContextMenu。

    2.按照上面的定义,ContextMenu可以在右键点下的时候显示,但是不能在鼠标按下Menu键的时候显示,可以让右键弹出的键盘事件还有shift+F10。具体参见http://social.msdn.microsoft.com/Forums/en/wpf/thread/01d0e981-156c-4dff-a588-bbe184cef398?prof=required

    3.menu键为右面ctrl左边的键,对应Key枚举为Key.Apps。F10很多时候是system key,所以,判断是否是shift+F10用下面的代码:Keyboard.Modifiers == ModifierKeys.Shift && (e.SystemKey == Key.F10 || e.Key == Key.F10)。

    4.可以通过Setter和EventSenter设置ContextMenu的ItemContainerStyle来设置所有item的属性。

    5.VerticalOffset可以设置垂直偏移,ContextMenuService.SetVerticalOffset(UIElement)可以设置ContextMenu的垂直偏移,一次设置,一直生效。

    6.ContextMenuService.PlacementMode(UIElement)可以设置ContextMenu的放置方法,例如设置成top,可以放到element上面,如果设置成relative,则根据左上角,进行偏移,偏移量为5中设置的值。

    7. 在xaml中设置了contextMenu的offset会使得contextMenu无论placementMode是什么,都会有那个offset。

    8.如果按照1的方法,那么键盘事件,HierarchicalDataTemplate中的控件是得不到焦点的,因为焦点总会被相应的TreeViewItem得到,因此,在控件上按menu键,不会弹出右键菜单,因为没有焦点。

    9.TreeView有selectedItem,得到的是当前选中的项,如果选中的项的ItemSource是ObservableCollection<object>那么会返回相应的object。

    10.TreeViewItem有Selected事件,并且可以在9的情况中得到选中的treeViewItem,可以在在其中设置TreeView的tag,方便以后得到selected的TreeViewItem,得到的代码如下:

private void TreeView_OnItemSelected(object sender, RoutedEventArgs e) 

     treeView.Tag = e.OriginalSource;

}当然也可以通过sender得到,但是sender需要考虑事件路由,到底是什么item触发了事件。

    11.每个控件有focus方法,调用,获得焦点,焦点获得有区域,一个点获得焦点,这个点一级其上层都会有相应事件,例如Panel上有个button,button有个click事件,如果button不处理,Panel也会处理,详细内容可以研究事件路由http://msdn.microsoft.com/zh-cn/magazine/cc785480.aspx

   12.可以通过treeView.ItemContainerGenerator.ContainerFromItem(treeView.SelectedItem)得到当前节点直接下层节点item对应的treeViewItem(按照9中设置)。具体情况可以参见:http://social.msdn.microsoft.com/Forums/zh-CN/silverlightzhchs/thread/ec4856c0-548e-4262-a9cb-4829b596ab65/

    13. 可以用FindName方法找到HierarchicalDataTemplate或其他DataTemplate中的Item,具体方法如下:http://msdn.microsoft.com/zh-cn/library/system.windows.frameworktemplate.findname.aspx

    14.DockPanel以及各种容器在PreviewKeyDown后似乎会改focus,有待验证。

    15.键盘焦点和鼠标焦点是不同的,具体查看keyboard.FocusedElement。

    16.貌似wpf中事件路由的走向在preview事件中是由上到下,否则是由下到上,这个没仔细看……

    17.可以在选中一个TreeViewItem时focus到里面的control上,具体方法参见:http://stackoverflow.com/questions/1612566/how-to-set-focus-to-a-control-in-a-treeviewitem-when-selected

    18. ToolTip是鼠标移上时所显示的item。

    19. 可以设置UIElement的focusable属性设置是否可以被focus上。也可以通过FocusManager静态类来处理焦点事件。

    20. 可以通过e.handled设置事件路由是否继续响应还是停止在某个控件上。

以后将进行整理,使有价值的显示的更清楚,并更成体系。

抱歉!评论已关闭.