【WPF学习】第二十三章 列表控件
WPF提供了许多封装项的集合的控件,本章介绍简单的ListBox和ComboBox控件,后续哈会介绍更特殊的控件,如ListView、TreeView和ToolBar控件。所有这些控件都继承自ItemsControl类(ItemsControl类本身又继承自Control类)。
ItemsControl类添加了所有基于列表的控件都使用的基本功能。最显著的是,它提供了填充列表项的两种方式。最直接的方法是代码或XAML将列表项直接添加到Items集合中。然而,在WPF中使用数据绑定的方法更普遍。使用数据绑定方法,需将ItemsSource属性设置为希望显示的具有数据项集合的对象(后续章节介绍与列表数据绑定相关的更多内容)。
ItemsControl类之后的继承橙子有些混乱。一个主要分支是选择器(selector),包括ListBox、ComboBox以及TabControl。这些控件都继承自Selector类,并且都具有跟踪当前选择项(SelectedItem)或其位置(SelectedIndex)的属性,封装列表项的控件是另一个分支,以不同方式选择列表项。该分支包括用于菜单、工具栏以及树的类——所有这些类都属于ItemsControl,但不是选择器。
为了充分发挥所有ItemsControl控件的功能,需要使用数据绑定。即使不从数据库甚至外部数据源获取数据,也同样如此。WPF数据绑定非常普遍,可使用各种数据,包括自定义的数据对象和集合。但现在还不需要考虑数据绑定的细节。现在,先快速浏览一下ListBox控件和ComboBox控件。
一、ListBox
ListBox类代表了一种最常用的Windows设计——允许用户从长度可变的列表中选择一项。
如果将SelectionMode属性设置为Multiple或Extended,ListBox类还允许选择多项。在Multiple模式下,可通过单击项进行选择或取消选择。在Extended模式下,需要按下Ctrl键选择其他项,或按下Shift键选择某个选项范围。在这两种多选模式下,可用SelectedItems集合替代SelectedItem属性来获取所有选择的项。
为向ListBox控件中添加项,可在ListBox元素中嵌套ListBoxItem元素。例如,下面是一个包含颜色列表的ListBox:
<ListBox>
<ListBoxItem>Yellow</ListBoxItem>
<ListBoxItem>Blue</ListBoxItem>
<ListBoxItem>Green</ListBoxItem>
<ListBoxItem>Red</ListBoxItem>
<ListBoxItem>LightBlue</ListBoxItem>
<ListBoxItem>Black</ListBoxItem>
</ListBox>
不同控件采用不同方式处理嵌套的内容。ListBox控件在它的Items集合中存储每个嵌套的对象。
ListBox控件是一个非常灵活的控件。它不仅可以包含ListBoxItem对象,也可以驻留其他任意元素。这是因为ListBoxItem类继承自ContentControl类,从而ListBoxItem能够包含一段嵌套的内容。如果该内容继承自UIElement类,它将ListBox控件中呈现出来。如果是其他类型的对象,ListBoxItem对象会调用ToString()方法并显示最终的文本。
例如,如果决定创建一个包含图像的列表,可使用如下标记:
<ListBox>
<ListBoxItem>
<Image Source="happyface.jpg"></Image>
</ListBoxItem>
<ListBoxItem>
<Image Source="redx.jpg"></Image>
</ListBoxItem>
</ListBox>
实际上ListBox控件足够职能,它能隐式地创建所需的ListBoxItem对象。这意味着可直接在ListBox元素中放置对象。厦门市一个更复杂的示例,该示例使用嵌套的StackPanel对象组合文本和图像内容:
<Window x:Class="Controls.ImageList"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ImageList" Height="300" Width="300">
<ListBox Margin="5" SelectionMode="Multiple" Name="lst" SelectionChanged="lst_SelectionChanged">
<StackPanel Orientation="Horizontal">
<Image Source="happyface.jpg" Width="30" Height="30"></Image>
<Label VerticalAlignment="Center">A Happy face</Label>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Image Source="redx.jpg" Width="30" Height="30"></Image>
<Label VerticalAlignment="Center">A Warning face</Label>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Image Source="happyface.jpg" Width="30" Height="30"></Image>
<Label VerticalAlignment="Center">A Happy face</Label>
</StackPanel>
</ListBox>
</Window>
ImageListBox
在该例中,StackPanel面板变成被ListBoxItem封装的项。该标记创建的富列表如图下图所示:
利用在列表框中的嵌套任意元素的能力,可创建出各种基于列表的控件,而不必使用其他类。例如,Windows窗体的哦该凝聚项中CheckedListBox类,该类显示在每个项的旁边都具有复选框的列表。在WPF中不需要这一特殊类,因为完全可使用标准的ListBox控件快速构建相同的效果:
<Window x:Class="Controls.CheckBoxList"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CheckBoxList" Height="300" Width="300">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions> <ListBox Name="lst" SelectionChanged="lst_SelectionChanged"
CheckBox.Click="lst_SelectionChanged" >
<CheckBox Margin="3">Option 1</CheckBox>
<CheckBox Margin="3">Option 2</CheckBox>
<CheckBox Margin="3">Option 3</CheckBox>
</ListBox>
<StackPanel Grid.Row="1" Margin="0,10,0,0">
<TextBlock>Current selection:</TextBlock>
<TextBlock Name="txtSelection" TextWrapping="Wrap"></TextBlock>
<Button Margin="0,10,0,0" Click="cmd_CheckAllItems">Examine All Items</Button>
</StackPanel>
</Grid>
</Window>
CheckBoxList
当在列表内部使用不同元素时需要注意一点。当读取SelectedItem值时(以及SelectedItems和Items集合),看不到ListBoxItem对象——反而将看到放入到列表中的对象。在CheckedListBox示例中,这意味着SelectedItem提供了CheckBox对象。
例如,下面是一些响应SelectionChanged事件触发的代码。这些代码获取当天选中CheckBox对象并显示该项是否被选中:
private void lst_SelectionChanged(object sender, RoutedEventArgs e)
{
// Select when checkbox portion is clicked (optional).
if (e.OriginalSource is CheckBox)
{
lst.SelectedItem = e.OriginalSource;
} 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);
}
在下面的代码片段中,类似的代码遍历选项集合以确定哪一项被选中(对于使用复选框的多项选择列表,可以编写类似的代码来遍历选中项的集合)。
private void cmd_CheckAllItems(object sender, RoutedEventArgs e)
{
StringBuilder sb = new StringBuilder();
foreach (CheckBox item in lst.Items)
{
if (item.IsChecked == true)
{
sb.Append(
item.Content + " is checked.");
sb.Append("\r\n");
}
}
txtSelection.Text = sb.ToString();
}
最终效果如下所示:
在列表框中手动放置项时,由你决定是希望直接插入项还是在ListBoxItem对象中明确地包含每项。第二种方法通常更清晰,也更繁琐。最重要的考虑事项是一致性。例如,如果在列表中放置StackPanel对象,ListBox.SelectedItem对象将是StackPanel。如果放置由ListBoxItem对象封装的StackPanel对象,ListBox.SelectedItem对象将是ListBoxItem,所以可进行响应编码。
ListBoxItem提供了少许额外功能,通过这些功能可得到直接嵌套的对象。换言之,ListBoxItem定义了可以读取(或设置)的IsSelected属性,以及用于通知何时选中的Selected和Unselected事件。然而,可使用ListBox类的成员得到类似功能,如SelectedItem属性(或SelectedItems属性)以及SelectionChanged事件。
有趣的是,当使用嵌套对象方法时,有一项技术可为特定的对象检索ListBoxItem封装器。技巧是使用常被忽视的ContainerFromElement()方法。下面的代码使用该技术检查列表中的第一个条目是否被选中:
ListBoxItem item=(ListBoxItem)lst.ContainerFromElement((DependencyObject)lst.SelectedItems[]);
MessageBox.Show("IsSelected:"+item.IsSelected.ToString());
二、ComboBox
ComboBox控件和ListBox控件类似。该控件包含ComboBoxItem对象的集合,既可以显示地也可以隐式地创建该集合。与ListBoxItem类似,ComboBoxItem也是可以包含任意嵌套元素的内容控件。
ComboBox类和ListBox类之间的重要区别是他们在窗口中呈现自身的方式。Combox控件使用下拉列表,这意味着一次只能选择一项。
如果希望允许用户在组合框中通过输入文本选项一项,就必须将IsEditable属性设置为true,并且必须确保选项集合中存储的是普遍的纯文本的ComboBoxItem对象,或是提供了有意义的ToString()表示的对象。例如,如果使用Image对象填充可编辑的组合框,那么在上面显示的文本将只有Image类的全名,这用处不大。
ComboBox控件的局限之一在于当使用自动改变尺寸功能时该控件改变自身尺寸的方法。ComboBox控件加宽自身以适应它的内容,这意味着当从一项移到另一项是它会改变自身大小。但没有简便的方法告诉ComboBox控件使用包含项的最大尺寸。相反,需要为Width属性提供硬编码的值,而这并不理想。
下面是一个简单的示例:
<Window x:Class="Controls.ComboBoxTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ComboBoxTest" Height="300" Width="300">
<StackPanel>
<ComboBox Margin="5">
<StackPanel Orientation="Horizontal">
<Image Source="happyface.jpg" Width="30" Height="30"></Image>
<Label VerticalAlignment="Center">A Happy face</Label>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Image Source="redx.jpg" Width="30" Height="30"></Image>
<Label VerticalAlignment="Center">A Warning face</Label>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Image Source="happyface.jpg" Width="30" Height="30"></Image>
<Label VerticalAlignment="Center">A Happy face</Label>
</StackPanel>
</ComboBox>
</StackPanel>
</Window>
ComboBoxTest
最终效果图如下所示:
【WPF学习】第二十三章 列表控件的更多相关文章
- WP8.1学习系列(第二十三章)——到控件的数据绑定
在本文中 先决条件 将控件绑定到单个项目 将控件绑定到对象的集合 通过使用数据模板显示控件中的项目 添加详细信息视图 转换数据以在控件中显示 相关主题 本主题介绍了如何在使用 C++.C# 或 Vis ...
- WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Dat ...
- 【转】WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要内容: DataGrid自定义样式: ListView自定义样式: 二.Dat ...
- WPF学习(一)--布局控件简介
WPF的4种基本布局介绍 1.Grid的布局 这个就没啥特别好说的,其实,基本上复杂的布局,都需要用到Grid. 主要就是对行和列进行进行设置和定义. 1.行表格 列表格: 包含行和列的表格 2.St ...
- WPF自定义控件与样式(9)-树控件TreeView与菜单Menu-ContextMenu
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 菜单M ...
- WPF自定义控件与样式(10)-进度控件ProcessBar自定义样
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Pro ...
- 【WPF学习】第五十九章 理解控件模板
最近工作比较忙,未能及时更新内容,敬请了解!!! 对于可视化树的分析引出了几个有趣问题.例如,控件如何从逻辑树表示扩张成可视化树表示? 每个控件都有一个内置的方法,用于确定如何渲染控件(作为一组更基础 ...
- 【WPF开发备忘】使用MVVM模式开发中列表控件内的按钮事件无法触发解决方法
实际使用MVVM进行WPF开发的时候,可能会用到列表控件中每行一个编辑或删除按钮,这时直接去绑定,发现无法响应: <DataGridTemplateColumn Header="操作& ...
- 第三部分:Android 应用程序接口指南---第二节:UI---第二章 输入控件
第2章 输入控件 输入控件是应用程序中用户接口的一种交互式组件.Android提供了大量的可供人们在UI中使用的控件,比如按钮.文本区域.(带滑块的)进度条.复选框.缩放按钮以及切换按钮等等. 在UI ...
随机推荐
- [vue/no-parsing-error] Parsing error: x-invalid-end-tag.eslint-plugin-vue
[vue/no-parsing-error] Parsing error: x-invalid-end-tag.eslint-plugin-vue 解决方案:vscode里面选择设置->搜索 ...
- Android studio 使用git仓库记录
studio 绑定git settings --> verson control -->git 在项目文件目录右击打开git bash here操作界面 查看git项目安装位置 找到id_ ...
- Visual Studio Team Services使用教程【6】:Readers tfs组checkin权限修改
你也可以只开启部分代码的权限 把上面开启的整个应用的权限先去掉 只开启一个文件的权限 2017.4.23之后建议朋友看下面的帖子 TFS2017 & VSTS 实战(繁体中文视频) Visua ...
- CString::CompareNoCase与CString::Compare的区别
转载:https://blog.csdn.net/lingdxuyan/article/details/4362116 函数原型:int CompareNoCase( LPCTSTR lpsz ) c ...
- SpringBoot-Swagger整合zuul智能列表
SpringBoot-Swagger整合zuul智能列表 简介 可能大家都有用过swagger,可以通过ui页面显示接口信息,快速和前端进行联调. 现在基本都是多模块微服务化,每个服务都有这样的ui页 ...
- 开发者请注意:Python2 的最后版本将于 4 月发布,但它确实是在 1 月 1 日就寿命终止了!
2020 年 1 月 1 日是 Python2 的寿命终止日,这个日期在两年前经"Python之父" Guido van Rossum 宣布,此后一直成为开发者社区翘首以盼的一天. ...
- 【题解】HDU Homework(倍增)
[题解]HDU Homework(倍增) 矩阵题一定要多多检查一下是否行列反了... 一百个递推项一定要存101个 说多了都是泪啊 一下午就做了这一道题因为实在是太菜了太久没写这种矩阵的题目... 设 ...
- $CH$ $0x50$ & $0x51$ 做题记录
[X]$Mr.Young's\ Picture\ Permutations$ 前面这儿写了挺多道辣,,,懒得写辣$QAQ$ (后面所有同上都是同这个$QwQ$ [X]$LCIS$ 做过了,看这儿 $u ...
- $exLucas$学习笔记
本来不打算写了的,,,但是感$jio$理解起来还是有点儿难度的来着,,,$so$还是瞎写点儿趴$QAQ$ $exLucas$主要有三步: 1)唯一分解$mod$并预处理$p^{k}$以内的阶乘 2)计 ...
- AES Base64 C++加密工具
最近写了一段C++ 的AES 加密的工具,在github 上找了很多工具,都不太好用,Star数字比较的高的一个,只能加密16个字节的,加密数字长数据,会出现乱码,不能使用 这里附上代码,文件以供大家 ...