WPF控件(子类)

内容控件

内容控件是更特殊的控件类型,它能拥有并显示一件内容。技术上,内容控件是能包含单个嵌套元素的控件。一个子元素的限制将内容控件与布局容器区分开来。布局容器可以拥有任意个嵌套元素。

当然,你仍然能把多个内容包装到内容控件中。诀窍是把它们都包裹到单个容器中,诸如一个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>

甚至可以在按钮中放置其他内容控件,如文本框,按钮、组合框。虽然这样做不太合理,但是这是可以的。

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)
{
    StringBuilder 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[0]);
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页。


<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值