WPF,Silverlight与XAML读书笔记第二十四 - 控件之六 – Items控件之菜单&其它

说明:本系列基本上是《WPF揭秘》的读书笔记。在结构安排与文章内容上参照《WPF揭秘》的编排,对内容进行了总结并加入一些个人理解。

 

菜单也是一类Items控件。WPF中有两类菜单 – Menu与ContextMenu(上下文菜单)。

 

Menu(WPF)

Menu类在ItemsControl的基础上添加了IsMainMenu属性。

  • IsMainMenu:当为True时,用户按下Alt键或F10键,菜单将获得焦点。

    类似其他Items控件,Menu的项可以是任何东西,但是总是应该使用MenuItem及Separator对象。下面给一个示例:

XAML:

 1 <Menu HorizontalAlignment="Left" Name="menu1" Width="200" Height="22" VerticalAlignment="Top" >
 2     <MenuItem Header="_File">
 3         <MenuItem Header="_New..."></MenuItem>
 4         <MenuItem Header="_Open..."></MenuItem>
 5         <Separator/>
 6         <MenuItem Header="Sen_d To">
 7             <MenuItem Header="My Documents"></MenuItem>
 8             <MenuItem Header="Recipient"></MenuItem>
 9         </MenuItem>
10     </MenuItem>
11 </Menu>

效果图(运行时):

 

MenuItem

    MenuItem是带头的Items控件(继承自HeaderedItemControl),这种控件类似于带头的内容控件。对于MenuItem,其头实际上就是文字,如下图所示:

    另外,与Button,Label相同,MenuItem使用下划线前缀支持访问键,上面的例子也使用了这个特性。

MenuItem的属性:

  • Icon:设置MenuItem旁边的区域,可以是任意类型的对象,通常是一副小图片。
  • IsCheckable:使MenuItem的行为像一个CheckBox控件。
  • InputGestureText:用一个相关手势来标识一个项,如一个键盘快捷方式。
  • Command:可以将命令通过这个属性绑定到MenuItem。

提示:只设置InputGestureText并不会给一个控件绑定如一个键盘快捷方式,正确的操作是将命令设置给其Command属性。同时这个命令关联到的Input Gesture会自动设置到这个属性。下图展示了这个过程:

 

提示:当把一个RouteUICommand赋给MenuItem的Command属性时,MenuItem的Header会被设置为Command的Text属性,显式设置Header可以重载该行为。

  

MenuItem的事件有Checked,Unchecked,SubmenuOpened,SubmenuClosed和Click等。

  • Click:不同于Command,Click可以给按钮增加一个通用的行为。

 

Separator

    放在MenuItem中间用来分隔两个菜单项,Separator也用于ToolBar和StatusBar控件中。

技巧:让Menu垂直排列

实现这种效果,类似于我们之前做的让ListBox横排,这次要更改Menu的面板。

代码:

1 <Menu.ItemsPanel>
2     <ItemsPanelTemplate>
3         <!--StackPanel,Orientation属性默认就是水平的,无需设置-->
4         <StackPanel />
5     </ItemsPanelTemplate>
6 </Menu.ItemsPanel>

 

 

ContextMenu(WPF)

    不同于Menu,不能直接把ContextMenu放入一个元素树中,可以通过将其设置给另一个控件的ContextMenu属性(这个ContextMenu属性定义于FrameworkElement及FrameworkContentElement中,在其它控件中往往是作为附加属性出现)的方式来加载,当设置后,用户右击控件或控件有焦点的情况下按Shift+F10会显示这个菜单。示例:

XAML:

 1 <Label Height="28" Name="label1" Width="120" Background="Azure">
 2     <Label.ContextMenu>
 3         <ContextMenu>
 4             <MenuItem Header="_File">
 5                 <MenuItem Header="_New..."></MenuItem>
 6                 <MenuItem Header="_Open..."></MenuItem>
 7                 <Separator/>
 8                 <MenuItem Header="Sen_d To">
 9                     <MenuItem Header="My Documents"></MenuItem>
10                     <MenuItem Header="Recipient"></MenuItem>
11                 </MenuItem>
12             </MenuItem>
13         </ContextMenu>
14     </Label.ContextMenu>
15     右击出现菜单
16 </Label>

效果图(运行时):

ContextMenu的属性:

  • IsOpen:ContextMenu 是否可见
  • Placement:菜单左上角的位置,默认是鼠标指针处。

    类似于ToolTip有一个ToolTipService静态类,ContextMenu也有一个ContextMenuService来设置作用目标的属性。这个类中有许多附加属性,它们大多包装了定义于ContextMenu中的对应属性。示例:右击一个被禁用的元素时显示ContextMenu(可以使用ContextMenuService的ShowOnDisabled附加属性实现这个需求)。

XAML:

1 <Label ContextMenuService.ShowOnDisabled="True">
2 <Label.ContextMenu>
3 … …
4     </Label.ContextMenu>
5     右击出现菜单
6 </Label>

 

TreeView (WPF)

    TreeView控件在各种程序框架中均很常见,其用可展开和折叠的节点来分层显示数据。不同的系统主题会影响TreeView的外观。

    TreeView应当使用TreeViewItem来填充,TreeViewItem也是一种带头的控件,其Header属性包含当前项,Items集合保存着子项(也是TreeViewItem)。示例:

XAML:

 1 <TreeView>
 2     <TreeViewItem Header="Desktop">
 3         <TreeViewItem Header="Computer"></TreeViewItem>
 4         <TreeViewItem Header="Recycle"></TreeViewItem>
 5         <TreeViewItem Header="MyDocument">
 6             <TreeViewItem Header="Music"></TreeViewItem>
 7             <TreeViewItem Header="Pictures"></TreeViewItem>
 8         </TreeViewItem>
 9     </TreeViewItem>
10 </TreeView>

效果图(运行时- Windows7 Aero):

TreeViewItem的属性:

  • IsExpandedItem:当前TreeViewItem是否为展开状态。
  • IsSelected:当前TreeViewItem是否为选中状态。

TreeViewItem的事件:

  • Expanded,Collapsed,Selected与Unselected,基本上也对应了上述属性。

TreeViewItem支持的键盘导航:

  • 加号,减号:展开或折叠一个项
  • 方向键,Page Up,Page Down,Home与End可以从一个项向另一个项移动焦点。

提示:

  1. 在TreeView中要显示的用TreeViewItem 包装项(如Label,TextBlock等),这样做可以保证不会出现由于属性值继承所导致的奇怪问题。
  2. TreeView看上去像是一个选择器(Selector),其不是由Selector继承,由于TreeView项不能使用简单的整数索引来标识。TreeView定义了自己的SelectedItem以及SelectedValue(没有定义SelectedIndex),还有SelectedItemChanged事件(传给事件处理函数的参数会包括OldValue与NewValue项 – TreeView一次处理一个选择项)
 

ToolBar(WPF)

    使用ToolBar控件可以对许多小的按钮或其他控件进行分组,可以将菜单中的功能等以这样一种更容易访问的方式来展示。先展示一个ToolBar的示例:

XAML:

 1 <ToolBar VerticalAlignment="Top" Height="26"  >
 2     <Button>
 3         <Image Source="copy1.gif"/>
 4     </Button>
 5     <Separator/>
 6     <ToggleButton>
 7         <Image Source="bold.gif"/>
 8     </ToggleButton>
 9     <ToggleButton>
10         <Image Source="italic.gif"/>
11     </ToggleButton>
12     <ToggleButton>
13         <Image Source="underline.gif"/>
14     </ToggleButton>
15     <Separator/>
16     <ToggleButton>
17         <Image Source="left.gif"/>
18     </ToggleButton>
19     <ToggleButton>
20         <Image Source="right.gif"/>
21     </ToggleButton>
22     <ToggleButton>
23         <Image Source="justify.gif"/>
24     </ToggleButton>
25     <Separator/>
26     <Label>Zoom</Label>
27     <ComboBox SelectedIndex="0">
28         <ComboBoxItem>100%</ComboBoxItem>
29         <ComboBoxItem>75%</ComboBoxItem>
30         <ComboBoxItem>50%</ComboBoxItem>
31         <ComboBoxItem>25%</ComboBoxItem>
32     </ComboBox>
33     <Separator/>
34     <Button>
35         <Image Source="superscript.gif"/>
36     </Button>
37     <Button>
38         <Image Source="subscript.gif"/>
39     </Button>
40 </ToolBar>

效果图(运行时):

    ToolBar中的项可以是任意类型的内容,ToolBar重载了项的默认样式,所以放在ToolBar中的按钮,ComboBox不是我们常见的样子,分隔条也变成了垂直线这样我们常见的工具条的样式。

    ToolBar通常被放置在ToolBarTray这个FrameworkElement中(虽然其可以被放置在元素树的任何位置),放置的方式是作为ToolBarTray的ToolBars属性来设置。示例代码:

1 <ToolBarTray>
2     <ToolBarTray.ToolBars>
3         <ToolBar>
4             … …
5         </ToolBar>
6     </ToolBarTray.ToolBars>
7 </ToolBarTray>

ToolBarTray的属性:

  • ToolBars:如上,常被以属性元素的方式来设置ToolBarTray中的ToolBar。
  • IsLocked:用户是否可以拖拽ToolBar或重新定义的ToolBar。这个属性也被作为附加属性可以设置到每一个ToolBar上来单独定义这个特性。
  • Orientation:可以将其设置为Vertical使ToolBar的项垂直排列。

 

ToolBar的属性:

  • OverflowMode:这是一个附加属性,这个属性可以被设置在ToolBar的元素上来定义其溢出方式(溢出就是项超过ToolBar的显示范围时的处理方式,一般情况下多余项被移到溢出区域,通过点击ToolBar右侧小箭头可以访问这个溢出区域)。这个属性有三值表示三种溢出方式:AsNeeded(默认,按需溢出),Always或Never。

 

StatusBar(WPF)

    StatusBar通常处在窗口的底部用于显示状态信息,其将它的子元素横排。先看一个示例:

XAML:

 1 <StatusBar Height="26">
 2     <Label>StatusBar Item</Label>
 3     <Separator/>
 4     <Label>Zoom</Label>
 5     <ComboBox SelectedIndex="0">
 6         <ComboBoxItem>100%</ComboBoxItem>
 7         <ComboBoxItem>75%</ComboBoxItem>
 8         <ComboBoxItem>50%</ComboBoxItem>
 9         <ComboBoxItem>25%</ComboBoxItem>
10     </ComboBox>
11     <Separator/>
12     <Button>
13         <Image Source="justify.gif"/>
14     </Button>
15 </StatusBar>

不同于ToolBar,默认情况下StatusBar只为Separator提供了一个模版,以控制Separator被渲染为垂直线。

另外,StatusBar隐式的将其中的项包装在StatusBarItem中,你可以显示的进行包装,如下示例:

1 <StatusBar>
2     <StatusBarItem>
3         <Label>StatusBar Item</Label>
4     </StatusBarItem>
5 </StatusBar>

这样你就可以使用部分布局控件提供的附加属性来自定义这些项的位置。

技巧:将StatusBar按比例分割,并可以自动适应容器长度变化。

这个问题的解决办法仍然是前文用过的自定义控件的模版,可以用Grid作为StatusBar的ItemPanel,并通过配置Grid的列来实现这个效果。

 

 

本文完

 

参考:

《WPF揭秘》

posted @ 2012-06-01 12:21  hystar  阅读(475)  评论(0编辑  收藏  举报