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控件的更多相关文章

  1. 浅尝辄止——使用ActiveX装载WPF控件

    1 引言 使用VC编写的容器类编辑器,很多都可以挂接ActiveX控件,因为基于COM的ActiveX控件不仅封装性不错,还可以显示一些不错的界面图元. 但是随着技术不断的进步,已被抛弃的Active ...

  2. 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 ...

  3. 通过WinForm控件创建的WPF控件无法输入的问题

    今天把写的一个WPF程序发布到别的机器上执行,发现一个比较奇怪的问题:在那个机器上用英文输入法无法输入数字,非要切换到中文输入法才行:但在我的机器上却是好好的. 最开始以为是输入法的问题,弄了好一阵子 ...

  4. WPF控件--利用Winform库中的NotifyIcon实现托盘小程序

    WPF控件--NotifyIcon   运行界面如下所示:            图1                                             图2 代码很少,如下所示 ...

  5. (转)WPF控件开源资源

    (转)WPF控件开源资源 Textbox Drag/Drop in WPFhttp://www.codeproject.com/Articles/42696/Textbox-Drag-Drop-in- ...

  6. WPF控件模板

    引言:在进行WPF项目开发过程中,由于项目的需要,经常要对某个控件进行特殊的设定,其中就牵涉到模板的相关方面的内容.本文也是在自己进行项目开发过程中遇到控件模板设定时集中搜集资料后整理出来的,以供在以 ...

  7. 关于WinForm引用WPF窗体---在Winform窗体中使用WPF控件

    项目中有个界面展示用WPF实现起来比较简单,并且能提供更酷炫的效果,但是在WinForm中使用WPF窗体出现了问题,在网上找了一下有些人说Winform不能引用WPF的窗体,我就很纳闷,Win32都能 ...

  8. 我的WPF控件库——KAN.WPF.XCtrl(141105)

    自己开发的WPF控件库,只是初版,有扩展的Button,TextBox,Window.详细参见前几篇博文. WPF自定义控件(一)——Button:http://www.cnblogs.com/Qin ...

  9. Dev的WPF控件与VS2012不兼容问题

    在只有vs2010环境下Dev的wpf可以在视图模式下显示,但是安装vs2012后无法打开界面的视图模式,报错:无法创建控件实例! 发现是Dev的wpf控件与.net framework 4.5不兼容 ...

  10. 解决 CefSharp WPF控件不能使用输入法输入中文的问题(代码已提交到 github)

    首先,本文所有 代码已经提交到github,需要的可以直接从github获取:https://github.com/starts2000/CefSharp,希望可以帮助到有需要的朋友们. CEF 简介 ...

随机推荐

  1. navicat连接mysql8报错,错误提示为1251,原因及解决步骤

    一.错误原因: MySQL8.0版本的加密方式和MySQL5.0的不一样,连接会报错. 二.解决步骤: 1.在linux虚拟机上登录mysql 2.更改加密方式: ALTER USER 'root'@ ...

  2. c++基础_字母图形

    #include <iostream> #include <algorithm> using namespace std; int main(){ ,m=,c; cin> ...

  3. 创建Tensor

    目录 创建Tensor numpy, list numpy list zeros, ones, fill zeros ones fill random 打乱idx后,a和b的索引不变 constant ...

  4. rbac组件之角色操作(二)

    为了与stark组件分离,形成独立的模块,所以rbac数据表的操作需要单独进行操作,对角色表的操作. urls.py urlpatterns = [ re_path(r'^roles/list/$', ...

  5. gcc 编译多个源文件

    序 Linux 内核和许多其他自由软件以及开放源码应用程序都是用 C 语言编写并使用 GCC 编译的. 编译C++程序 编译.链接命令 -c 只编译不里链接 -o链接 例: g++ file1 -c ...

  6. Selenium IDE-自动化实战

    1.输入测试 Base URL 2.打开录制按钮(默认是录制状态,点击一下就是停止,再次点击,又继续录制) 3.在浏览器界面进行相关操作(比如输入selenium,点击搜索按钮,查看搜索结果),之后点 ...

  7. python pip 安装一些包找不到的问题 Could not find a version that satisfies....

    有时我们使用下载python 自带的pip 安装一些工具包时,会报如下错误 找不到满意的版本,这时就是我们的pip可能需要升级了,所以使用 python -m pip install --upgrad ...

  8. 一个简单的模板了解css+div网页布局

    直接附上最终效果图: index.html内容: <html> <!--20170730 soulsjie--> <head> <meta http-equi ...

  9. pdf & watermark & puppeteer

    pdf & watermark & puppeteer background image https://en.wikipedia.org/wiki/Watermark pdf &am ...

  10. BFS简单迷宫

    常见迷宫: 输入迷宫 启点 终点 然后求最短路径 BFS例题 用dist[][]数组来记录 启点到每个点的最短路径 #include <iostream> #include <fst ...