控件
什么是控件?
大多数流行的 UI 框架都提供类似于控件的抽象,而 WPF 采用了一种稍微不寻常的方
法,因为控件通常不直接负责它们自己的外观。 WPF 中的控件都是关于行为的,它们
遵从模板来提供视觉效果。许多 GUI 框架要求您在自定义控件外观时编写自定义控
许多 WPF 用户界面元素不是控件。例如,像矩形和椭圆形这样的形状没有内在行 为,它们只是外观。较低级别的元素直接从Control派生。通常它们派生自 FrameworkElement。
图 5‑1 显示控件如何适合程序。如您所见,控件的可见部分由其模板提供,而不是控件本身。
按钮 Button
设置按钮的快捷键 Alt+B
<Button Width="75" Click="Button_Click" Content="_Button"> </Button>
当按钮内容为非纯文本时:
<Button Width="75" Click="Button_Click" > <AccessText> _Button </AccessText> </Button>
RadioButton
单选按钮通常成组使用,一次只能选择一个按钮。对单选按钮进行分组的最简单方法是为它们提供一个共同的父级。
在示例 5‑6 中,两个单选按钮将组成一个组,因为它们共享同一个父项。
<StackPanel> <RadioButton>To be</RadioButton> <RadioButton>Not to be</RadioButton> </StackPanel>
有时您可能希望创建多个具有共同父级的不同组。您可以通过设置GroupName属性来实现,如示例 5‑7 所示。
示例 5‑7。按名称对单选按钮进行分组
<StackPanel> <RadioButton GroupName="Fuel">Petrol</RadioButton> <RadioButton GroupName="Fuel">Diesel</RadioButton> <RadioButton GroupName="Induction">Unforced</RadioButton> <RadioButton GroupName="Induction">Mechanical supercharger</RadioButton> <RadioButton GroupName="Induction">Turbocharger</RadioButton> </StackPanel>
Slider and Scroll Controls 滑块和滚动控件
Slider和ScrollBar在使用上非常相似。这两个控件都有一个Orientation属性,可以在垂直和水平
模式之间进行选择。它们都派生自一个公共基类RangeBase。这提供了定义控件表示的值范围的
Minimum和Maximum属性,以及保存当前选定值的Value属性。它还定义了SmallChange和
LargeChange属性,这两个属性分别决定了使用箭头键或 Page Up 和 Page Down 键调整时值的
变化量。当单击滑块两侧的滑块轨道部分时,也会使用LargeChange值。
ProgressBar 进度条
ProgressBar控件指示应用程序已完成多少长时间运行的进程。
ProgressBar派生自RangeBase,这是与上一节中讨论的滚动条和滑块控件相同的基类。
Text Controls 文本控件
WPF 提供了用于编辑和显示文本的控件。最简单的文本编辑控件是TextBox。默认情况下,它允许编辑单行文本,但
通过将AcceptsReturn设置为 true,它可以编辑多行。它提供基本的文本编辑功能:选择支持、系统剪贴板集成(剪
切、粘贴等)和多级撤消支持。
<StackPanel Orientation="Horizontal"> <TextBox Margin="5" VerticalAlignment="Center" Text="Single line textbox" /> <TextBox AcceptsReturn="True" Margin="5" Height="50" VerticalScrollBarVisibility="Visible" VerticalAlignment="Center" Text="Multiline textbox" /> <PasswordBox Margin="5" VerticalAlignment="Center" Password="Un5ecure" /> </StackPanel>
RichTextBox支持EditingCommands类定义的所有命令。这包括对常见格式操作的支持,例如粗
体、斜体和下划线。它们绑定到 Ctrl‑B、Ctrl‑I 和 Ctrl‑U 键盘快捷键。大多数编辑命令都有默认的键
盘输入手势,因此您无需执行任何特殊操作即可启用键盘访问格式操作。
TextBox和RichTextBox都提供内置的拼写检查。您需要做的就是将SpellCheck.IsEnabled附加
属性设置为True。
Label 标签
Label控件的用途是提供一个放置带有访问键的标题的位置。当按下
访问键时, Label会将焦点重定向到相关控件,在本例中为TextBox。
当按下Alt键时,标签上显示快捷键字母,再同时按下对应的字母时,光标跳转到相关TextBox框中。
<StackPanel > <Label Target="{Binding ElementName=nameText}">_Name:</Label> <TextBox x:Name="nameText" Width="70" /> <Label Target="{Binding ElementName=questText}">_Quest:</Label> <TextBox x:Name="questText" Width="70" /> </StackPanel>
ToolTip 提示
<StackPanel > <TextBox Width="100"> <TextBox.ToolTip> <ToolTip Content="Type something here" /> </TextBox.ToolTip> </TextBox> <TextBox Margin="10" Width="100" ToolTip="Type something here" /> <TextBox Width="100" > <TextBox.ToolTip> <TextBlock FontSize="25"> <Ellipse Fill="Orange" Width="20" Height="20" /> Plain text is <Italic>so</Italic> <Span FontFamily="Old English Text MT">last century</Span> <Ellipse Fill="Orange" Width="20" Height="20" /> </TextBlock> </TextBox.ToolTip> </TextBox> </StackPanel>
GroupBox and Expander 分组 和扩展器
GroupBox和Expander是非常相似的控件:它们都为任意内容提供了一个容器,并在顶部为标题
提供了一个位置。这些控件之间的主要区别在于Expander可以展开和折叠;用户可以单击左上角的箭头来隐藏和显示内容。 GroupBox始终显示其内容。
这两个控件都派生自HeaderedContentControl,后者又派生自ContentControl。因此,我们可以直接在控件中放置任何我们喜欢的内容
<StackPanel Orientation="Horizontal"> <GroupBox Header="Glass"> <Border Margin="2" Background="White" Padding="3"> <StackPanel> <RadioButton Content="Half-full" IsChecked="True" /> <RadioButton Content="Half-empty" /> </StackPanel> </Border> </GroupBox> <Expander Header="Glass" IsExpanded="True" Background="#def" VerticalAlignment="Center" MinWidth="90" Margin="10,0"> <Border Margin="2" Background="White" Padding="3"> <StackPanel> <RadioButton Content="Half-full" IsChecked="True" /> <RadioButton Content="Half-empty" /> </StackPanel> </Border> </Expander> </StackPanel>
HeaderedContentControl支持双重形式的内容模型:不仅Expander或GroupBox的主体可
以是您喜欢的任何内容,标题也可以。
List Controls 列表控件
WPF 提供了几个可以显示多个项目的控件。 ListBox、 ComboBox和ListView都可以呈现项目的线性序列。
TreeView呈现项目的层次结构。 TabControl可能看起来不像是ListBox 的明显亲戚,但它具有相同的基本特征:它显示一系列项目(标签页)并
让用户选择哪个是当前项目。所有这些控件共享一个公共基类ItemsControl。
<StackPanel> <ComboBox> <Button>Click!</Button> <TextBlock>Hello, world</TextBlock> <StackPanel Orientation="Horizontal"> <TextBlock>Ellipse:</TextBlock> <Ellipse Fill="Blue" Width="100" /> </StackPanel> </ComboBox> <ListBox> <Button>Click!</Button> <TextBlock>Hello, world</TextBlock> <StackPanel Orientation="Horizontal"> <TextBlock>Ellipse:</TextBlock> <Ellipse Fill="Blue" Width="100" /> </StackPanel> </ListBox> <TabControl> <TabItem Header="_Button"> <Button>Click!</Button> </TabItem> <TabItem> <TabItem.Header> <TextBlock FontSize="18" FontFamily="Palatino Lintype"> <AccessText>_Text</AccessText> </TextBlock> </TabItem.Header> <TextBlock>Hello, world</TextBlock> </TabItem> <TabItem> <TabItem.Header> <Ellipse Fill="Red" Width="30" Height="20"/> </TabItem.Header> <StackPanel Orientation="Horizontal"> <TextBlock>Ellipse:</TextBlock> <Ellipse Fill="Blue" Width="100" /> </StackPanel> </TabItem> </TabControl> <ListView> <Button>Click!</Button> <TextBlock>Hello, world</TextBlock> <StackPanel Orientation="Horizontal"> <TextBlock>Ellipse:</TextBlock> <Ellipse Fill="Blue" Width="100" /> </StackPanel> </ListView> </StackPanel>
您始终可以通过处理相关事件来了解所选项目何时
更改: TreeView的SelectedItemChanged和其他控件的SelectionChanged 。
此TabControl包含与之前相同的三个项目,但这次明确指定了TabItem元素。在其中的第一个
中, Header属性已设置为文本“_Button”。这使用了标题对内容模型的支持:这就是为什么我
List View 列表显示 用于数据绑定
ListView派生自ListBox,添加了对网格状视图的支持。要使用它,您必须为View属性
提供一个描述列表中列的GridView*对象。
<ListView> <ListView.View> <GridView AllowsColumnReorder="true"> <GridViewColumn Header="Name" /> <GridViewColumn Header="Line Spacing" /> <GridViewColumn Header="Sample" /> </GridView> </ListView.View> </ListView>
<ListView ItemsSource="{x:Static Fonts.SystemFontFamilies}"> <ListView.View> <GridView> <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Source}" /> <GridViewColumn Header="Line Spacing" DisplayMemberBinding="{Binding LineSpacing}" /> <GridViewColumn Header="Sample"> <GridViewColumn.CellTemplate> <DataTemplate> <TextBlock FontFamily="{Binding}" FontSize="20" Text="ABCDEFGabcdefg" /> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView> </ListView.View> </ListView>
Tree View 树视图
1 <TreeView> 2 <TreeViewItem Header="First top-level item" IsExpanded="True"> 3 <TreeViewItem Header="Child" /> 4 <TreeViewItem Header="Another child" IsExpanded="True"> 5 <TreeViewItem Header="Grandchild" /> 6 <TreeViewItem Header="Grandchild 2" /> 7 </TreeViewItem> 8 <TreeViewItem Header="A third child" /> 9 </TreeViewItem> 10 <TreeViewItem Header="Second top-level item"> 11 <TreeViewItem Header="Child a" /> 12 <TreeViewItem Header="Child b" /> 13 <TreeViewItem Header="Child c" /> 14 </TreeViewItem> 15 <TreeViewItem IsExpanded="True"> 16 <TreeViewItem.Header> 17 <StackPanel Orientation="Horizontal"> 18 <Ellipse Fill="Blue" Width="15" Height="15" /> 19 <TextBlock Text="Third top-level item" /> 20 <Ellipse Fill="Blue" Width="15" Height="15" /> 21 </StackPanel> 22 </TreeViewItem.Header> 23 <TreeViewItem Header="Child a" /> 24 <TreeViewItem Header="Child b" /> 25 <TreeViewItem Header="Child c" /> 26 </TreeViewItem> 27 </TreeView>
Menus 菜单
<StackPanel> <Menu> <MenuItem Header="_File"> <MenuItem Header="_New" /> <MenuItem Header="_Open..." /> <MenuItem Header="_Save" /> <MenuItem Header="Sa_ve As..." /> <Separator /> <MenuItem Header="Page Se_tup..." /> <MenuItem Header="_Print..." /> <Separator /> <MenuItem Header="E_xit" /> </MenuItem> <MenuItem Header="_Edit"> <MenuItem Header="_Undo" Command="Undo" /> <MenuItem Header="_Redo" Command="Redo"/> <Separator /> <MenuItem Header="Cu_t" Command="Cut"/> <MenuItem Header="_Copy" Command="Copy"/> <MenuItem Header="_Paste" Command="Paste"/> <MenuItem Header="_Delete" Command="Delete"/> <Separator /> <MenuItem Header="Select _All" Command="SelectAll"/> </MenuItem> <MenuItem Header="_Help"> <MenuItem Header="Help _Topics" /> <MenuItem Header="_About..." /> </MenuItem> </Menu> <TextBox TextWrapping="Wrap" AcceptsReturn="True" Height="300" > <TextBox.ContextMenu> <ContextMenu> <MenuItem Header="Cut" Command="Cut" /> <MenuItem Header="Copy" Command="Copy" /> <MenuItem Header="Paste" Command="Paste" /> </ContextMenu> </TextBox.ContextMenu> </TextBox> </StackPanel>
了一个同时具有快捷键和访问键的菜单项。
<MenuItem Header="_New" InputGestureText="Ctrl+N" />
Toolbars 工具栏
<ToolBarTray> <ToolBar> <Button> <Canvas Width="16" Height="16" SnapsToDevicePixels="True"> <Polygon Stroke="Black" StrokeThickness="0.5" Points="2.5,1.5 9.5,1.5 12.5,4.5 12.5,15 2.5,15"> <Polygon.Fill> <LinearGradientBrush StartPoint="1,1" EndPoint="0.2,0.7"> <GradientStop Offset="0" Color="#AAA" /> <GradientStop Offset="1" Color="White" /> </LinearGradientBrush> </Polygon.Fill> </Polygon> <Polygon Stroke="Black" Fill="DarkGray" StrokeThickness="0.5" StrokeLineJoin="Bevel" Points="9.5,1.5 9.5,4.5 12.5,4.5" /> </Canvas> </Button> <Button> <Canvas Width="16" Height="16" > <Polygon Stroke="Black" StrokeThickness="0.5" Fill="Khaki" SnapsToDevicePixels="True" Points="0.5,14.5 0.5,4.5 1.5,3.5 6.5,3.5 8.5,5.5 12.5,5.5 12.5,14.5" /> <Polygon Stroke="Black" SnapsToDevicePixels="True" StrokeThickness="0.5" Points="1.5,14.5 4.5,7.5 15.5,7.5 12.5,14.5" > <Polygon.Fill> <LinearGradientBrush StartPoint="0.25,0" EndPoint="0.5,1"> <GradientStop Offset="0" Color="#FF4" /> <GradientStop Offset="1" Color="#CA7" /> </LinearGradientBrush> </Polygon.Fill> </Polygon> <Path Stroke="Blue" StrokeThickness="1" Data="M 8,2 C 9,1 12,1 14,3" /> <Polygon Fill="Blue" Points="15,1 15.5,4.5 12,4" /> </Canvas> </Button> </ToolBar> <ToolBar> <Button>Second toolbar</Button> <CheckBox IsChecked="True">Choice</CheckBox> </ToolBar> </ToolBarTray>
GridSplitter 网格分割器(用户可以手动调节左右宽度)
<Grid Height="100" Width="400"> <Grid.ColumnDefinitions> <ColumnDefinition Width="1*" /> <ColumnDefinition Width="6" /> <ColumnDefinition Width="2*" /> </Grid.ColumnDefinitions> <Ellipse Grid.Column="0" Fill="Red" /> <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" /> <Ellipse Grid.Column="2" Fill="Blue" /> </Grid>