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页。

最新文章

  1. mongoose - 让node.js高效操作mongodb
  2. yii2权限控制rbac之rule详细讲解
  3. nginx+php-fpm+mysql分离部署详解
  4. Swift中类与结构的初始化
  5. CI框架获取post和get参数 CodeIgniter
  6. Linux Shell 03 条件测试
  7. NRF51822之GPIOTE使用
  8. unity jiaoben
  9. 【积硅计划】html标签
  10. android 46 service
  11. POJ 1830.开关问题(高斯消元)
  12. 基于jQuery编写的页面跳转简单的小插件
  13. 回调函数 callback 的简单理解
  14. XAlign - Xcode插件 - 对齐代码
  15. ContentResolver,ContentProvider,ContentObserver使用记录
  16. MathJax使用指南
  17. (转)Spring Boot (十三): Spring Boot 小技巧
  18. Numpy中array数据操作
  19. Mysql查看表的建表语句
  20. ansible和python的zabbix_api批量添加rsync服务的监控

热门文章

  1. 树莓派 - 通过sysfs操控GPIO
  2. virtualenvwrapper.sh: There was a problem running the initialization hooks. If Python could not import the module virtualenvwrapper.hook_loader, check that virtualenvwrapper.........(解决办法)
  3. stark组件之注册与路由系统(三)
  4. 数据结构代码实现之队列的链表实现(C/C++)
  5. python 用 PIL 模块 画验证码
  6. MFC对话框使用CPrintDialog实现打印,指定打印机、后台打印
  7. [bzoj3531][Sdoi2014][旅行] (主席树+树链剖分)
  8. 整体二分初识--POJ2104:K-th Number
  9. struts面试题及答案【重要】
  10. Linux下汇编语言学习笔记3 ---