分类:
2010-09-14 17:57:21
简单容器
WPF包含了许多内建的内容控件,它们没有类似Button控件的可以被点击的概念,但是却有它们自己存在的独特性。
1.Label
Label是经典控件,和以前的应用一样,它可以存放一些文字。作为一种WPF的内容控件,它可以用Content属性存储任何内容——Button、Menu等,但是Label只对文本有用。
可以使用WPF中不同的方法把文字放在屏幕上,比如可以使用一个TextBlock元素,但是Label控件的独到之处是它支持访问键(access key)。有了访问键,可以在用户按下Alt键和某一个字母键时,对Lable文本中的某个字母做特殊处理。当用户按下Alt键和某一个字母键时,Label允许你指定哪个元素获得焦点。在字母之前增加一条下划线就可以指派某个字母(该字母下出现的下划线是由Windows的设置决定),然后用Label的Target属性(UIElement类型)来选择目标元素。
要在另一个控件中使用Label控件的访问键支持,可以把它和TextBox控件配合使用。当Alt+U键被按下时:
Target的值是通过数据绑定(data binding)来设置的,这部分内容会在第9章里提及。
在C#中,你可以用下面的代码把它设置为TextBox控件的实例(假设Label控件的名字是userNameLabel):
提示 Label和Button控件是通过处理字母之前的下划线来实现访问键的,比如_Open或者Save _As。(Win32和Windows Forms使用[&],但使用下划线对XML更友好。)如果真的需要在字符里用到下划线,请用两条连贯的下划线。
2.ToolTip
ToolTip控件把它的内容放在一个浮动框中,当把鼠标移过与之关联的控件时,就会显示ToolTip的内容,鼠标移开以后内容会消失。图4-4显示了一个典型的ToolTip,具体的实现代码如以下XAML:
图4-4 WPF ToolTip |
ToolTip类绝对不能被直接放在UI元素树中,它必须被赋给另一个元素的ToolTip属性(在FrameworkElement和FrameworkContentElement中定义)。
提示 当设置元素的ToolTip属性时,甚至不需要使用ToolTip常见问题解答类!这个属性是Object类型,如果把它设为任何一个非ToolTip对象,这个属性的实现会自动创建一个ToolTip,并且使用这个属性的值作为ToolTip的内容。因此,图4-4的XAML代码可以被简化成如下形式:
由于WPF内容控件相当灵活,WPF ToolTip可以控制任何你想得到的东西!代码清单4-1 演示了如何创建一个Microsoft Office风格的Screen常见问题解答,运行结果如图4-5所示。
代码清单4-1 一个复杂的ToolTip,与Microsoft Office Screen常见问题解答类似
图4-5 像2007版office系统中的Screen- Tip在WPF中创建也并不容易 |
尽管ToolTip的内容能包含像Button这样的互动控件,但它们不会获得焦点,并且你不能点击或者与它们交互。
可能你想在ToolTip出现和消失时做些事情,为此ToolTip定义了Open和Closed事件。它还可以定义许多属性来调节它的行为,比如,它的布置,是否应该一直保持打开直到显式地关闭它,甚至是否要渲染阴影。有时候你可能想在多个控件上应用相同的ToolTip,尽管你希望不同控件上的ToolTip行为有所不同。对于这些情况,ToolTipService静态类可以满足你的需求。
ToolTipService定义了一些附加属性,它能够被设置在任何一个使用ToolTip的元素上(而不是在ToolTip本身设置)。它有几个与ToolTip一样的属性(因为ToolTip的值可能有冲突,所以它优先级更高),但是比ToolTip多了几个属性。例如,ShowDuration控制鼠标指针悬停在一个元素上多久应该显示ToolTip;InitialShowDelay控制停止和ToolTip第1次被显示之间的时间间隔。你可以把ShowDuration添加到第1个ToolTip的示例中,如下所示:
当鼠标滑过一个被禁用的元素时,怎样才能让ToolTip显示?
只需使用ToolTipService类的ShowOnDisabled附加属性!从XAML来看,对于Button来说,它看起来就像:
或者在C#中,可以调用附加属性相对应的静态方法:
3.Frame
就像所有其他内容控件一样,Frame控件也可以包含任何内容,但是它是把内容从其余的UI中分离了出来。例如,当属性在Frame中时,它们将不从元素树继承。从很多方面来看,WPF的Frame行为很像HTML的Frame。
谈到HTML,Frame的要求是它除了渲染WPF内容以外还要可以渲染HTML内容!Frame的Source属性是System.Uri类型的,可以被设置为任何一个HTML(或者XAML)页面,例如:
Frame内建WPF导航跟踪支持,它既可以应用到HTML上,又可以应用到XAML内容上,这点会在第7章中讲解。
所以,你可以把Frame控件当作一个功能更强大的“Microsoft Web Browser”ActiveX控件或者Windows Forms WebBrowser控件。不幸的是,当Frame宿主了HTML之后,它有一些局限,但其他的WPF控件没有这样的限制(因为它的HTML渲染实现依赖于Win32)。例如,HTML内容总是在WPF内容顶部被渲染,它不能应用位图效果,透明度也不能改变,以及其他一些限制。Frame也不支持对任意类型字符串或者HTML流的渲染;它的内容必须是一个路径或者一个URL所指向的松散文件。(如果需要显示作为资源嵌入的HTML,最好的选择是使用Windows Forms WebBrowser控件技术,这将在第15章详细讲解。)
提示 Image元素是另一种带有Source属性的WPF类,Source属性可以用来保存那些存储在URL、本地磁盘、一个程序集中的图片。在本章中,Image被用了好几次,而在第8章中还会用到它。
Frame的Content属性
虽然Frame是一种有Content属性的内容控件,但是从XAML角度来看,它并不把Content当作一种属性。换句话说,XAML中的Frame元素不支持子元素。你必须显式地以如下方式使用Content属性:
为了达到这种效果,Frame通过使用空的ContentPropertyAttribute来标记自己,这样可以覆盖ContentControl基类中的[ContentProperty("Content")]。但是为什么它会有影响?
WPF的设计者之所以实现它,是因为把Source属性设置为一个外部文件的作法是Frame的标准使用方法,这样可以弱化Frame的Content属性。Frame作为ContentControl的唯一原因是为了与NavigationWindow保持一致性,这将在第7章中讨论。注意,如果你同时设置了Source和Content属性,Content优先!