6 WPF控件
WPF控件分类:
- 内容控件
- 标题内容控件
- 文本控件
- 列表控件
- 基于范围的控件
- 日期控件
控件类
控件是与用户交互的元素。控件可以获得焦点,能接受键盘或鼠标的输入。
所有控件的基类是System.Windows.Control类,这类包括一些基本功能:
- 对齐
- tab序列
- 背景、前景、边界
- 文本内容的字体
背景和前景刷子
控件包括两个属性Background和Foreground属性,这两个属性使用Brush对象。刷子对象的派生类包括SolidColorBrush、LinearGradientBrush、和TileBrush类。
用代码设置颜色
为名为cmd的按钮设置背景色:
cmd.Background = new SolidColorBrush(Colors.AliceBlue);
通过Colors类的静态属性获得预定义的颜色,将它传递给构造函数创建一个新的SolidColorBrush实例,将它赋值给按钮的背景属性。
也可使用系统颜色:
cmd.Background = new SolidColorBrush(SystemColors.ControlColor);
SystemColors类也提供预制的属性返回SolidColorBrush对象:
cmd.Background = SystemColors.ControlBrush;
你能创造一个颜色对象,依靠提供R,G,B值(红绿蓝)。每个值是从0到255一个数字:
int red = 0; int green = 255; int blue = 0;
cmd.Foreground = new SolidColorBrush(Color.FromRgb(red, green, blue));
你能设置颜色的透明度,通过调用Color.FromArgb()方法,为其传递alpha值。alpha值为255是完全不透明,而为0是完全透明。
用XAML设置颜色
在XAML中,只需要提供颜色的名字或颜色值,其他的工作由解析器负责。
<Button Background="Red">A Button</Button>
用 #rrggbb 或 #aarrggbb格式提供颜色值:
<Button Background="#FFFF0000">A Button</Button>
刷子支持自动改变通知。刷子从System.Windows.Freezable类派生而来。Freezable类有两个状态:可读状态,只读状态(冻结)
控件类还定义了BorderBrush和BorderThickness属性。
字体
Control类定义几个字体相关的属性。决定控件文本的外观。这些属性列在表6-1。
名字 | 描述 |
FontFamily | |
FontSize | |
FontStyle | |
FontWeight | |
FontStretch |
Control类没有定义任何使用它字体的属性。然而许多控件包括Text属性,没有定义为Control基类的成员。明显地,除非被派生类使用,字体属性没有任何意义。
字体家族
鼠标光标
内容控件
内容控件是更特殊的控件类型,它能拥有并显示一件内容。技术上,内容控件是能包含单个嵌套元素的控件。内容控件与布局容器的区别是,内容控件只能包含一个子元素,而布局容器可以拥有任意个子元素。
当然,你仍然能把多个内容包装到内容控件中。诀窍是把它们都包裹到单个容器中,诸如一个StackPanel、或一个Grid。例如,Window类本身是一个内容控件。明显地,窗口经常有大量内容,但是,它们都被包裹在一顶层的容器中(典型地,Grid)。
所有的内容控件起源于ContentControl抽象类。内容控件类主要包括:一些公共控件Label、ToolTip。各种按钮控件Button、RadioButton、CheckBox。一些更专用的ScrollViewer、UserControl。Window本身是个内容控件。
最后,存在一个内容控件子集,依靠从HeaderedContentControl类派生,增加了一层继承。包括GroupBox,TabItem,和Expander控件。这些控件有内容区域和标题区域,标题区域用于显示某种标题。
另外,用于导航的Frame、用于其他控件内部的ListBoxItem、StatusBarItem等也是内容控件。
Content属性
ContentControl类添加一个Content属性,接受单个对象。Content属性支持任何类型的对象,但是它把对象分为两组,并且区别对待:
- 不派生自UIElement的对象:内容控件调用ToString()获得这些控件的文本,然后显示文本。
- 派生自UIElement的对象:这些对象包括所有可视元素。使用UIElement.OnRender()方法,被显示在内容控件内部。
例如,一个提供简单字符串的按钮:
<Button Margin="3">Text content</Button>
使用Image类放置一个图像到按钮内:
<Button Margin="3">
<Image Source="happyface.jpg" Stretch="None" />
</Button>
放置一个包裹图像和文本的容器到按钮内:
<Button Margin="3">
<StackPanel>
<TextBlock Margin="3">Image and text button</TextBlock>
<Image Source="happyface.jpg" Stretch="None" />
<TextBlock Margin="3">Courtesy of the StackPanel</TextBlock>
</StackPanel>
</Button>
甚至可以在按钮中放置其他内容控件,如文本框,按钮、组合框。虽然这样做不太合理,但是WPF允许这样。
Window是内容控件,但是他只能是顶级容器,不能嵌套在其他元素中。
内容控件的其他属性包括:
HasContent属性,为真时表示控件有内容。
ContentTemplate属性,是一个告诉控件如何显示对象的模板。使用ContentTemplate,更智能地显示非UIElement派生来的对象。你可以获取对象的各种属性值,并整理放入更复杂的标记中。
对齐内容
HorizontalContentAlignment、VerticalContentAlignment取值为Top, Bottom, Left, Right、Center、Stretch
Padding属性指控件边界到其内容的距离。
HorizontalContentAlignment,VerticalContentAlignment,和Padding属性定义在Control类中,不在更特殊的ContentControl类。因为,一些不是内容控件的控件也有某种内容。例如,TextBox不是内容控件,它使用上述属性设置输入文本。
WPF内容哲学
内容控件减少了控件的数量,但是,增加了一点控件的复杂度。
标签(Label)
标签控件主要的功能是助记键,使链接控件获得焦点的快捷键。标签控件的Target属性指定链接控件。为了设置Target,使用绑定表达式指向另一个控件。
<Label Target="{Binding ElementName=txtA}">Choose _A</Label>
<TextBox Name="txtA"></TextBox>
<Label Target="{Binding ElementName=txtB}">Choose _B</Label>
<TextBox Name="txtB"></TextBox>
标签文本下划线指明快捷键。如果真需要一个下划线,可以连续输入两个下划线转义。
同时按下Alt和所指定的快捷键,链接的控件就会获得焦点。例如,在本例中,按下Alt+A,焦点就会跳到txtA控件。
如果不需要助记键功能,可以考虑使用TextBlock。
按钮类的控件
按钮类的控件包括Button、CheckBox、和RadioButton。他们都从ButtonBase派生。
Click支持命令功能。
ClickMode属性,ClickMode.Release,ClickMode.Press,ClickMode.Hover
按钮也支持快捷键。
按钮
每个窗口可以有取消按钮和默认按钮,通过设置按钮的IsCancel、IsDefault属性。详见159页。
另外,还有一个容易混淆的IsDefaulted属性,见160页侧边条。
ToggleButton、RepeatButton
从ButtonBase派生的类还有三个:
- GridViewColumnHeader
- RepeatButton
- ToggleButton
RepeatButton 和ToggleButton都位于System.Windows.Controls.Primitives名字空间。常用于组合、或派生成其他控件,也可以单独使用。
CheckBox
CheckBox和RadioButton都是从ToggleButton派生。
ToggleButton添加了一个IsChecked属性,它是一个可空布尔值。
为了在WPF标记中分配一个空值,使用空标记扩展,如下所示:
<CheckBox IsChecked="{x:Null}">A check box in indeterminate state</CheckBox>
ToggleButton还有一个IsThreeState属性,它决定是否可以设置复选框为未定态。默认为false。
ToggleButton类定义三事件:Checked,Unchecked,和Indeterminate事件。
RadioButton
默认情况下,单选按钮按它们的容器分组。RadioButton的GroupName属性允许你覆盖这行为。
<StackPanel>
<GroupBox Margin="5">
<StackPanel>
<RadioButton>Group 1</RadioButton>
<RadioButton>Group 1</RadioButton>
<RadioButton>Group 1</RadioButton>
<RadioButton Margin="0,10,0,0" GroupName="Group2">Group 2</RadioButton>
</StackPanel>
</GroupBox>
<GroupBox Margin="5">
<StackPanel>
<RadioButton>Group 3</RadioButton>
<RadioButton>Group 3</RadioButton>
<RadioButton>Group 3</RadioButton>
<RadioButton Margin="0,10,0,0" GroupName="Group2">Group 2</RadioButton>
</StackPanel>
</GroupBox>
</StackPanel>
不需要使用GroupBox容器包裹单选按钮组,但这是一个普遍的约定。GroupBox显示一个边界和一个标题。
专用的容器
内容控件也包括一些专用的容器。
ScrollViewer直接从ContentControl继承。
ContentControl类派生了HeaderedContentControl类,这个类包括一个标题和一个内容。标题和内容都可以嵌套单个子元素。HeaderedContentControl类派生了几个子类:GroupBox,TabItem,和Expander。
ScrollViewer
尽管ScrollViewer能包裹任何元素,但是一般情况下,它包裹一个布局容器。
<ScrollViewer>
<Grid Margin="3,3,10,3">
</Grid>
</ScrollViewer>
VerticalScrollBarVisibility属性,此属性是ScrollBarVisibility枚举。Visible、Auto、Disabled。默认值是Visible。
HorizontalScrollBarVisibility属性,默认值是Hidden。
编程控制滚动
详见171页。
自定义滚动
详见172页。
GroupBox
GroupBox从HeaderedContentControl类派生。
<GroupBox Header="A GroupBox Test" Padding="5"
Margin="5" VerticalAlignment="Top">
<StackPanel>
<RadioButton Margin="3">One</RadioButton>
<RadioButton Margin="3">Two</RadioButton>
<RadioButton Margin="3">Three</RadioButton>
<Button Margin="3">Save</Button>
</StackPanel>
</GroupBox>
GroupBox仍然要求一个布局容器布置内容。GroupBox没有特别的功能,只是一个装饰控件。
TabItem
TabItem代表TabControl的一个选项卡。TabItem类添加了IsSelected属性,指示选项卡是否是TabControl当前显示的选项卡。
<TabControl Margin="5">
<TabItem Header="Tab One">
<StackPanel Margin="3">
<CheckBox Margin="3">Setting One</CheckBox>
<CheckBox Margin="3">Setting Two</CheckBox>
<CheckBox Margin="3">Setting Three</CheckBox>
</StackPanel>
</TabItem>
<TabItem Header="Tab Two">
...
</TabItem>
</TabControl>
通过设置TabControl的TabStripPlacement属性,可以将选项卡从正常的顶部放到侧边。
正如Content属性,Header属性能接受任何类型的对象。这是一个例子:
<TabControl Margin="5">
<TabItem>
<TabItem.Header>
<StackPanel>
<TextBlock Margin="3" >Image and Text Tab Title</TextBlock>
<Image Source="happyface.jpg" Stretch="None" />
</StackPanel>
</TabItem.Header> <StackPanel Margin="3">
<CheckBox Margin="3">Setting One</CheckBox>
<CheckBox Margin="3">Setting Two</CheckBox>
<CheckBox Margin="3">Setting Three</CheckBox>
</StackPanel>
</TabItem> <TabItem Header="Tab Two"></TabItem>
</TabControl>
Expander
见175页。
文本控件
WPF包括三文本输入控件:TextBox,RichTextBox,和PasswordBox。PasswordBox直接从Control派生。TextBox和RichTextBox控件派生自TextBoxBase。
不同于内容控件,文本框仅限于他们能包含的内容类型。TextBox永远存储一个字符串(Text属性)。PasswordBox也处理字符串内容(Password属性),尽管它使用SecureString。只有RichTextBox有能力存储更世故的内容:一个FlowDocument。
多行文本
MaxLength属性,设置TextBox允许的最大字符数。
TextWrapping属性,设置为Wrap或WrapWithOverflow,表示自动换行。
MinLines和MaxLines属性,设置TextBox的最小(最大)可见的行数。
LineCount属性,可以检索出文本框中的文本有多少行。
VerticalScrollBarVisibility、HorizontalScrollBarVisibility属性,设置滚动条的可视状态。
AcceptsReturn属性,设置为真表示TextBox接受回车。默认情况下,TextBox不接受回车。
AcceptsTab属性为真表示接受Tab键,默认情况下,TextBox不接受Tab键。
IsReadOnly属性,阻止编辑文本。
文本选择
见180页。
拼写检查
见181页。
密码框
见183页。
列表控件
列表控件的基类是ItemsControl类。
每个ItemsControl类都有项目列表。有二种方法填充项目列表。最直白的方法是直接添加项到项集合,使用代码或XAML。更常用的方法是数据绑定。这种方法是设置ItemsSource属性为要显示的数据项集。
ItemsControl类派生的一个主要分支为Selector类,包括ListBox, ComboBox,和TabControl类。可以跟踪当前选择项(SelectedItem),或它的位置(SelectedIndex)。
其余的列表类不支持当前项,直接从ItemsControl类派生。这些类包括Menu、Toolbar、TreeView等。
ListBox
设置SelectionMode属性为Multiple可以多选。在多选模式下,要使用SelectedItems集合而不是SelectedItem。
添加列表框项:
<ListBox>
<ListBoxItem>Green</ListBoxItem>
<ListBoxItem>Blue</ListBoxItem>
<ListBoxItem>Yellow</ListBoxItem>
<ListBoxItem>Red</ListBoxItem>
</ListBox>
ListBoxItem派生自ContentControl。
例如,创建一个图像的列表框:
<ListBox>
<ListBoxItem>
<Image Source="happyface.jpg"></Image>
</ListBoxItem>
<ListBoxItem>
<Image Source="happyface.jpg"></Image>
</ListBoxItem>
</ListBox>
可以省略上例的ListBoxItem,列表框足够智能,可以识别列表项:
<ListBox>
<StackPanel Orientation="Horizontal">
<Image Source="happyface.jpg" Width="30" Height="30"></Image>
<Label VerticalContentAlignment="Center">A happy face</Label>
</StackPanel> <StackPanel Orientation="Horizontal">
<Image Source="redx.jpg" Width="30" Height="30"></Image>
<Label VerticalContentAlignment="Center">A warning sign</Label>
</StackPanel> <StackPanel Orientation="Horizontal">
<Image Source="happyface.jpg" Width="30" Height="30"></Image>
<Label VerticalContentAlignment="Center">A happy face</Label>
</StackPanel>
</ListBox>
下面是一个列表项为复选框的例子:
<ListBox Name="lst" SelectionChanged="lst_SelectionChanged"
CheckBox.Click="lst_SelectionChanged">
<CheckBox Margin="3">Option 1</CheckBox>
<CheckBox Margin="3">Option 2</CheckBox>
</ListBox>
如果你没有使用ListBoxItem填充列表项,当你读SelectedItem值时,将不会得到ListBoxItem对象,而是你放置到列表中的对象。在上例中,SelectedItem将提供一个CheckBox对象。
下面代码获取当前的选择项,显示该项目是否被选中。
private void lst_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (lst.SelectedItem == null) return;
txtSelection.Text = String.Format(
"You chose item at position {0}.\r\nChecked state is {1}.",
lst.SelectedIndex,
((CheckBox)lst.SelectedItem).IsChecked);
}
如果你希望知道哪一个项目失去选择,你能使用SelectionChangedEventArgs对象的RemovedItems属性。类似地,AddedItems属性告诉你哪一个项目被添加到选择。在单选模式,无论何时选择改变,永远是一项目被添加和一项目被移除。在multiple或extended模式,就不一定了。
下面是遍历列表项目集合的代码:
private void cmd_ExamineAllItems(object sender, RoutedEventArgs e)
{
var sb = new StringBuilder();
foreach (CheckBox item in lst.Items)
{
if (item.IsChecked == true)
{
sb.Append(item.Content);
sb.Append(" is checked.");
sb.Append("\r\n");
}
}
txtSelection.Text = sb.ToString();
}
ListBoxItem也有一些额外的功能:IsSelected属性、Selected事件和Unselected事件。这些功能也可以通过ListBox的SelectedItem属性和SelectionChanged事件实现。
有趣地,存在一个技术,当你使用嵌套对象方法时,获取指定对象的ListBoxItem包裹器。诀窍是ContainerFromElement()方法。这是使用这个技术的代码检查第一项目是否是列表的被选择项:
var item = (ListBoxItem)lst.ContainerFromElement(
(DependencyObject)lst.SelectedItems[]);
MessageBox.Show("IsSelected: " + item.IsSelected.ToString());
ComboBox
组合框用法与列表框基本相同。
如果你允许用户通过在组合框键入文本来选择一个项目,你必须设置IsEditable属性为true,并且你必须确保你存储平凡的仅文本的ComboBoxItem对象,或一个提供有意义的ToString()表示法的对象。例如,如果你填充一个可编辑的带有图像对象组合框,文本出现在上面的部分是Image类的全名,这不是非常使用。
基于范围的控件
基于范围的控件基类是RangeBase类,从Control类派生。包括ScrollBar, Slider, 和ProgressBar类。RangeBase类的属性包括:
Value、Maximum、Minimum、SmallChange、LargeChange
因为有ScrollView控件,ScrollBar很少用。现在关注Slider和ProgressBar。
Slider
见188页
ProgressBar
见190页
日期控件
见190页。
6 WPF控件的更多相关文章
- 浅尝辄止——使用ActiveX装载WPF控件
1 引言 使用VC编写的容器类编辑器,很多都可以挂接ActiveX控件,因为基于COM的ActiveX控件不仅封装性不错,还可以显示一些不错的界面图元. 但是随着技术不断的进步,已被抛弃的Active ...
- XMAL语法系列之-(2)---WPF控件继承图
WPF控件继承图 1 FrameworkElement 1.1 Panel(面板类元素) 1.1.1 Canvas 1.1.2 DockPanel 1.1.3 Grid 1.1.4 TabPanel ...
- 通过WinForm控件创建的WPF控件无法输入的问题
今天把写的一个WPF程序发布到别的机器上执行,发现一个比较奇怪的问题:在那个机器上用英文输入法无法输入数字,非要切换到中文输入法才行:但在我的机器上却是好好的. 最开始以为是输入法的问题,弄了好一阵子 ...
- WPF控件--利用Winform库中的NotifyIcon实现托盘小程序
WPF控件--NotifyIcon 运行界面如下所示: 图1 图2 代码很少,如下所示 ...
- (转)WPF控件开源资源
(转)WPF控件开源资源 Textbox Drag/Drop in WPFhttp://www.codeproject.com/Articles/42696/Textbox-Drag-Drop-in- ...
- WPF控件模板
引言:在进行WPF项目开发过程中,由于项目的需要,经常要对某个控件进行特殊的设定,其中就牵涉到模板的相关方面的内容.本文也是在自己进行项目开发过程中遇到控件模板设定时集中搜集资料后整理出来的,以供在以 ...
- 关于WinForm引用WPF窗体---在Winform窗体中使用WPF控件
项目中有个界面展示用WPF实现起来比较简单,并且能提供更酷炫的效果,但是在WinForm中使用WPF窗体出现了问题,在网上找了一下有些人说Winform不能引用WPF的窗体,我就很纳闷,Win32都能 ...
- 我的WPF控件库——KAN.WPF.XCtrl(141105)
自己开发的WPF控件库,只是初版,有扩展的Button,TextBox,Window.详细参见前几篇博文. WPF自定义控件(一)——Button:http://www.cnblogs.com/Qin ...
- Dev的WPF控件与VS2012不兼容问题
在只有vs2010环境下Dev的wpf可以在视图模式下显示,但是安装vs2012后无法打开界面的视图模式,报错:无法创建控件实例! 发现是Dev的wpf控件与.net framework 4.5不兼容 ...
- 解决 CefSharp WPF控件不能使用输入法输入中文的问题(代码已提交到 github)
首先,本文所有 代码已经提交到github,需要的可以直接从github获取:https://github.com/starts2000/CefSharp,希望可以帮助到有需要的朋友们. CEF 简介 ...
随机推荐
- HTTP实验:分别使用httpd-2.2和httpd-2.4实现
1. 需求描述 1.建立httpd服务,要求: (1) 提供两个基于名称的虚拟主机: www1.stuX.com,页面文件目录为/web/vhosts/www1:错误日志为/var/log/httpd ...
- Buffer.from(arrayBuffer[, byteOffset[, length]])
Buffer.from(arrayBuffer[, byteOffset[, length]]) arrayBuffer - 一个 TypedArray 或 new ArrayBuffer() 的 . ...
- django-2 models
一个model 对应DB的一张表 models 以类的形式表现: 一些字段.数据的一些行为 对类.类的对象 操作,无需写SQL = > object relation mapping ORM ...
- POJ1013称硬币【枚举】
Counterfeit Dollar Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 52474 Accepted: 16 ...
- Mybatis传递多个参数的4种方式(干货)
Mybatis传递多个参数的4种方式(干货)-----https://blog.csdn.net/youanyyou/article/details/79406486
- BNUOJ 1268 PIGS
PIGS Time Limit: 1000ms Memory Limit: 10000KB This problem will be judged on PKU. Original ID: 11496 ...
- [codeforces494B]Obsessive String
[codeforces494B]Obsessive String 试题描述 Hamed has recently found a string t and suddenly became quite ...
- CF601D:Acyclic Organic Compounds
给n<=300000的树,每个点上有一个字母,一个点的权值为:从该点出发向下走到任意节点停下形成的不同字符串的数量,问最大权值. 题目本身还有一些奇怪要求在此忽略.. Trie合并的模板题. # ...
- Linux中kill,pkill,killall和xkill命令汇总讲解
终止一个进程或终止一个正在运行的程式,一般是通过 kill .killall.pkill.xkill 等进行.比如一个程式已死掉,但又不能退出,这时就应该考虑应用这些工具. 另 外应用的场合就是在服务 ...
- poj——1470 Closest Common Ancestors
Closest Common Ancestors Time Limit: 2000MS Memory Limit: 10000K Total Submissions: 20804 Accept ...