- 所有控件都继承自System.Windows.Control类。
- 字体继承
当设置任何字体属性时,属性值都会流经嵌套的对象,例如,如果为顶级窗口设置了FontFamily属性,窗口中的所有控件都会得到相同的FontFamily属性值,除非为控件明确设置了不同的字体。这是因为字体属性是依赖属性,并且依赖属性能够提供的特性之一就是属性值继承。
属性值继承能够流经那些根本就不支持相应属性的控件,例如创建一个包含StackPanel面板的窗口,在StackPanel面板中有三个Label控件,可以为窗口设置FontSize属性,因为Window类继承自System.Windows.Control类,但是不能为StackPanel面板设置FontSize属性,因为它不是一个控件,但如果设置了窗口的FontSize属性,属性值仍然会经过StackPanel面板,到达其内部的标签,并改变标签的字体大小。
与字体一样,其它几个基本属性也使用属性值继承,在control类中,Foreground属性使用继承,Background属性不使用,在UIElement类中,AllowDrop、IsEnabled、IsVisible属性都使用属性继承,在FremeworkElement中,CultureInfo和FlowDirection属性也使用属性值继承, - 字体替换
在WPF中,可以将FontFamily属性设置为一个由逗号分割的字体选项列表,WPF将遍历列表查找在用户计算机上存在的字体。 如下按钮会使用Arial字体,如果Arial在用户计算机上不存在就会使用Comic Sans MS字体。
<Button FontFamily="Arial,Comic Sans MS,Technical Italic">A Button</Button>
使用System.Windows.Media.Fonts类的静态集合SystemFontFamilies集合,可以获得在当前计算机上已安装的所有字体的列表。
-
字体嵌入
处理不常见字体的另一种选择是在应用程序中嵌入字体,通过嵌入字体,应用程序就永远不会出现查找希望使用的字体问题。嵌入过程为:首先向应用程序添加字体文件,然后在VS中将此文件属性中的生成操作设置为Resource。接下来,在使用字体时,需要在字体家族名称之前添加字符序列”./# “,它表示当前文件夹。如:<Label FontFamily="./#草檀斋mozedong字体" FontSize="20" >草船借箭</Label> --被和谐字体
-
WPF的文本渲染
当使用比较小(小于15点的文本)的字体时,WPF文本渲染会使文本变得模糊,为了解决此问题,WPF增加了TextOptions.TextFormattingMode附加属性,并且将其设置为Display,默认值为Ideal.例如:<TextBlock Margin="5" FontSize="9">This is a Test.Display test is crisp at small sizes</TextBlock> <TextBlock TextOptions.TextFormattingMode="Display" Margin="5" FontSize="9">This is a Test.Display test is crisp at small sizes</TextBlock>
TextOptions.TextFormattingMode附加属性它仅是针对小尺寸文本的解决方案。
-
鼠标光标
可以为任何元素使用Cursor属性设置鼠标光标,该属性继承自FrameworkElement类,每个光标通过一个System.Windows.Input.Cursor对象表示。可以通过System.Windows.Input.Cursors类的静态属性获取所以标准的Windows鼠标光标。在XAML中设置鼠标光标示例如下:<Button Cursor="Help">Help</Button>
可以为一个按钮和包含它的窗口设置不同的光标,当鼠标移动到按钮上时,将显示为按钮设置的光标,而对于窗口中的其他区域则显示为窗口设置的光标。但是通过为父元素使用ForceCursor属性,父元素可以覆盖子元素的光标设置。
WPF支持自定义光标,可以使用普通的.cur光标文件,也可以使用.ani动画光标文件,为了使用自定义光标,需要为Cursor对象的构造函数传递光标文件的文件名或包含光标数据的流:Cursor customCursor = new Cursor(System.IO.Path.Combine(applicationDir, "stopwatch.ani")); this.Cursor = customCursor;
Cursor对象不直接支持Url资源语法,但可以使用Application.GetResourceStream()方法获取光标文件资源的数据流来设置自定义光标:
StreamResourceInfo sri = Application.GetResourceStream(new Uri("stopwatch.ani", UriKind.Relative)); Cursor customCursor = new Cursor(sri.Stream); this.Cursor = customCursor;
-
内容控件
所有内容控件都继承自抽象的ContentControl类,ContentControl.HasContent属性:如果在控件中有内容,它返回true. ContentControl.ContentTemplate属性:通过该属性,可以创建一个模板,用于告诉控件如何显示它不识别的对象,使用它,可以更加智能的显示非继承自UIElement的对象。
对齐内容:
在FrameworkElement基类中的HorizontalAlignment和VerticalAlignment属性,用于在容器中对齐不同的控件,而在控件中,使用HorizontalContentAlignment和VerticalContentAlignment属性决定内容控件中的内容如何和其边框对齐。
通过Margin属性可以在相邻元素之间添加空间,内容控件使用一个和Margin互补的Padding属性在控件边缘和内容边缘之间插入空间。-
Label
Label控件支持记忆符,记忆符是能够为链接的控件设置焦点的快捷键,Label控件通过Target属性支持此功能,为了设置Target属性,需要使用一个指向另一个控件的绑定表达式:<Label Content="姓名_A" Target="{Binding ElementName=txtName}" /><TextBox Name="txtName" />
如果需要显示不支持记忆符的内容,就应使用轻量级的TextBlock元素,与Label控件不同,TextBlock元素还通过它的TextWrapping属性支持换行。
-
按钮
继承自ButtonBase类的控件有Button、GridViewColumnHeader、RepeatButton、ToggleButton,而CheckBox和RadioButton继承自ToggleButton。ButtonBase定义了Click事件并添加了对命令的支持,从而允许为更高层的应用程序任务触发按钮。ButtonBase还添加了ClickMode属性,该属性决定何时引发Click事件以响应鼠标动作。默认值为ClickMode.Release,表示当单击鼠标并释放鼠标键时引发Click事件,如果设置为ClickMode.Press表示当鼠标第一次按下时引发Click事件,如果设置为ClickMode.Hover表示将鼠标移动到按钮上并且在按钮上悬停一会儿时引发Click事件。
所有按钮都支持访问键,它和Label中的记忆符类似,添加下划线字符标识访问键,如果用户按下了Alt键和访问键,就会触发按钮单击事件。-
Button 它提供三个属性:IsCancel、IsDefault、IsDefaulted
IsCancel:如果将它设置为true,按钮就成为窗口的取消按钮,在当前窗口的任何地方如果按下Escape键,就会触发该按钮。
IsDefault:如果将它设置为true,按钮就成为默认按钮,它的行为取决于焦点在窗口中的位置,如果焦点位于一个非按钮控件上,默认按钮具有蓝色阴影,几乎像是有焦点,如果按下Enter,就会触发默认按钮。如果焦点位于另一个按钮上,此时如果按下Enter,会触发当前按钮而不是默认按钮。
IsDefaulted:如果另一个控件具有焦点并且该控件不接受Enter输入,那么对于默认按钮,IsDefaulted属性会返回true,在这种情况下,按下Enter键会触发该按钮。 -
GridViewColumnHeader:当使用一个基于网格的ListView控件时,该类表示一列可以单击的标题。
-
RepeatButton:只要按钮保持按下状态,该类就不断的触发Click事件。
-
ToggleButton:它和RepeatButton都不是抽象类,所以在用户界面中可以直接使用它们,该类表示具有两个状态的按钮,当单击该按钮时,它会保持按下状态,直到再次单击该按钮以释放它。
-
RadioButton:它继承自ToggleButton。它通常由它们的容器进行分组,但它添加了一个GroupName属性,用于控制如何对单选按钮进行分组,通过GroupName可以控制在不同的容器或同一容器中进行分组而覆盖这一默认行为。
-
CheckBox:它继承自ToggleButton,ToggleButton类有IsChecked属性,它是一个可空的Boolean类型,在XAML中为IsChecked属性赋null值如下:
<CheckBox IsChecked="{x:Null}">A check box in indeterminate state</CheckBox>
-
- 工具提示
使用工具提示的最简单的办法是为元素设置ToolTip属性,ToolTip是在FrameworkElement中定义的,所以所有放在WPF窗口中的元素都可以使用该属性:
<Button ToolTip="This is a tooltip" Content="I have a Tooltip" />
<CheckBox IsChecked="{x:Null}"> <CheckBox.ToolTip> <StackPanel> <TextBlock>Image and text</TextBlock> <Image Source="/WpfApplication1;component/LuFei.jpg"></Image> <TextBlock>Image and text</TextBlock> </StackPanel> </CheckBox.ToolTip> <CheckBox.Content>A check box in indeterminate state</CheckBox.Content> </CheckBox>
有几个工具提示属性不能通过ToolTip类的属性进行配置,此时需要使用ToolTipService类,它定义了许多与ToolTip相同的属性,它的所有属性都是附加属性,所以可以在控件标签中直接设置它们,InitialShowDelay属性:设置当鼠标悬停在元素上时,工具提示显示之前的延迟时间(单位毫秒),ShowDruation属性:设置如果用户不移动鼠标,在工具提示消失之前显示的时间。
<Button ToolTip="This is a tooltip" ToolTipService.InitialShowDelay="10" ToolTipService.ShowDuration="10000" Content="test" />
- Popup控件
Popup控件在许多方面和ToolTip控件类似,但它们没有相互继承关系,它也只能包含单一元素(存储在Popup.Child中,而不像ToolTip存储在Content中),该单一元素可以包含任何WPF元素,它和ToolTip一样也可以延伸到窗口的边界。示例如下:
<TextBlock> You can use a Popup to provide a link for a specific <Run TextDecorations="Underline" MouseEnter="Run_MouseEnter"> term </Run> of interest. </TextBlock> <Popup Name="popLink" StaysOpen="False" Placement="Mouse" MaxWidth="200" PopupAnimation="Slide" AllowsTransparency="True"> <Border BorderBrush="Beige" BorderThickness="2" Background="White"> <TextBlock Margin="10" TextWrapping="Wrap"> For more information,see <Hyperlink NavigateUri="www.baidu.com" Click="Hyperlink_Click"> Wikipedia </Hyperlink> </TextBlock> </Border> </Popup>
private void Run_MouseEnter(object sender, MouseEventArgs e) { popLink.IsOpen = true; } private void Hyperlink_Click(object sender, RoutedEventArgs e) { Process.Start(((Hyperlink)sender).NavigateUri.ToString()); }
Popup和ToolTip之间的重要区别有:- Popup控件永远不会自动显示,为了显示Popup控件必须设置IsOpen属性。
- Popup.StaysOpen属性默认设置为true,并且Popup控件会一直显示,直到明确的将IsOpen属性设置为false,如果将StaysOpen属性设置为false,当用户在其他地方单击鼠标时,Popup控件就会消失。
- Popup.PopupAnimation属性,将把IsOpen属性设置为true时,通过该属性可以控制Popup控件进入视野的方式。
- Popup控件可以接受焦点,因此,可以在其内部放置与用户交互的控件,它是使用它的主要原因。
- Popup控件在System.Windows.Controls.Primitive名称空间中定义的,因为它的更常见的用法是用作更复杂控件的构件。在外观修饰方面会发现它和其它控件的区别很大,特别是如果希望看到内容,必须设置Background属性,因为Popup控件不会从包含它的窗口继承背景设置,并且需要自己添加边框。
-
- 特殊容器控件
特殊容器控件包括:ScrollViewer、GroupBox、TabItem、Expander,因为它们只能包含单一元素,所以它们通常需要与一个布局容器结合使用。- ScrollViewer控件
ScrollViewer类提供的用来控制滚动的方法:- LineUp()、LineDown():这两个方法向上或向下移动的效果相当于单击一次垂直滚动条两端的箭头按钮。
- PageUp()、PageDown():这两个方法向上或向下滚动一整屏,相当于在滚动滑块的上面或下面单击滚动条表面。
- 用于水平滚动的类似方法:LineLeft()、LineRight()、PageLeft()、PageRight()。
- ScrollToEnd()、ScrollToHome()、ScrollToVerticalOffset()、ScrollToLeftEnd()、ScrollToRightEnd()、ScrollToHorizontalOffset()。
- HeaderedContentControl类也是一个继承自ContentControl的类,它表示同时具有单一元素内容(存储在Content属性中)和单一元素标题(存储在Header属性中)的容器。有三个类继承自HeaderedContentControl类:GroupBox、TabItem和Expander。
- GroupBox:它显示为一个具有圆角和标题的方框,经常用于对数量不多的相关控件进行分组。
- TabItem:它表示TabControl中的一页,TabItem类添加的唯一的一个有意义的属性是IsSelected,该属性表示选项卡当前是否正显示在TabControl控件中。
可以使用TabStripPlacement属性,使各个选项卡在选项卡控件的侧边显示,而不是在正常的顶部位置显示。
与Content属性一样,Header属性也可以接受任何类型的对象。 - Expander:它包装了一块内容,通过单击一个小箭头按钮可以显示或隐藏所包含的内容。
可以设置IsExpanded属性来控制Expander开始是折叠的还是展开的,默认折叠。
可以设置ExpandDirection属性来控制Expander的扩展方向,当折叠Expander时,箭头总是指向将要展开的方向。
可以使用Expanded和Collapsed事件实现延迟加载。例如,如果创建Expander控件的内容非常耗时,可能会直到要显示时才检索这些内容。或者可能希望在显示之前更新内容。
- ScrollViewer控件
- 文本控件
WPF提供了三个用于文本输入的控件:TextBox、RichTextBox、PasswordBox。PasswordBox控件继承自Control类,而TextBox和RichTextBox继承自TextBoxBase类。
TextBox:
可能希望允许用户在多行文本框中通过按下Enter键输入回车(通常,在文本框中按下Enter键会触发默认按钮),只需将 AcceptsReturn属性设置为true。也可以设置AcceptsTabs属性,从而允许用户插入Tab键,否则,Tab键会根据Tab键焦点顺序将焦点移动到下一个可以得到焦点的控件上。
通过将AutoWordSelection属性设置为true,当在文本中拖动鼠标时文本框每次会选择整个单词。
TextBox还提供了一个更特殊的功能,即集成的 拼写检查,该功能会在文本中不能识别的单词下面添加红色的波浪下划线,用户可以右击不能识别的单词并从可能正确的单词列表中进行选择。要为TextBox控件开户拼写检查功能,只需简单的设置 SpellCheck.IsEnabled 依赖项属性即可。拼写检查是WPF特有的功能,并且该功能不依赖于其它软件(如Office)。拼写检查根据为键盘配置的输入语言来决定使用哪个词典。可以通过TextBox控件的Language属性覆盖默认设置,该属性继承自FrameworkElement类,或者可以在<TextBox>元素中设置xml:lang特性。然而,WPF拼写检查目前只支持四种语言:英语、西班牙语、法语和德语。在WPF的以前的版本中,拼写检查不支持定制功能,WPF 4允许添加一系列被认为没有拼写错误的单词(并且在适当的时候,将被用作右击建议)。为此,必须创建一个词典文件,一个.lex扩展名的文本文件。在词典文件中,添加单词列表。在单独的行中放置每个单词,单词的顺序没有关系。而且可以添加一个地区ID指定词典只能用于某种特定的语言。如英语:#LID 1033,西班牙语:#LID 3082,法语:#LID 1036,德语:#LID 1031。自定义词典功能只是简单的使用词典中的单词扩充已经支持的语言。一旦创建了词典文件,就得使用SpellCheck.CustomDictionaries属性关联一个指向自定义词典的Uri对象。
PasswordBox:
PasswordBox看起来和TextBox类似,但是它通过显示一个圆圈符号字符串来屏蔽它的实际字符(可以通过设置PasswordChar属性选择不同的屏蔽字符)。此别,PasswordBox不支持剪贴板,所以不能复制内部的文本。
PasswordBox在内部通过使用System.Security.SecureString对象保存密码字符,SecureString是一个纯文本对象,它以加密的方式在内存中保存,用于加密字符串的密钥是随机生成的,且存储在一块从来不会写入到磁盘的内存中,最终的结果是即使计算机崩溃,恶意用户也不可能通过检查页面文件来检索密码数据,即使找到,也只能找到加密版本。SecureString类还提供了Dispose()方法用于在需要时消毁密码数据。当控件被消毁时,PasswordBox控件会自动地为保存在内存中的SecureString对象调用Dispose()方法。
RichTextBox: - 列表控件
ListBox:
ComboBox: - 基于范围的控件
WPF提供了三个使用范围概念的控件:ScrollBar、ProgressBar及Slider,它们都继承自RangeBase类。这些控件使用一个在特定最小值和最大值之间的数值。
ScrollBar:通常不直接使用ScrollBar,而是使用更高级的ScrollViewer控件。
Slider:当数字本身不是特别重要时可以使用该控件设置数值。
ProgressBar:通常使用它作为一个长时间运行状态的指示器,甚至可能不知道该任务需要执行多长时间,可以通过将 IsIndeterminate属性设置为true,而不再使用Minimum、Maximum和Value属性,ProgressBar控件会周期性的显示一个从左向右的绿色脉冲,这是通用的Windows约定,表示工作正在进行中。 - 日期控件
WPF提供两种日期控件:Calender、DatePicker。