
在实际应用中,列表控件主要用于显示列表格式的数据,然后供用户选择,常见的列表控件有ComboBox(下拉列表框),ListBox(列表框),CheckedListBox(带复选框的列表框),ListView(带图标的列表框),TreeView(树状结构的列表视图),今天我们以一些简单的小例子,简述列表控件的常见应用方式,仅供学习分享使用,如有不足之处,还请指正。

概述
列表控件,主要是用于列出选项的 Windows 窗体控件,如果要向用户提供可供选择的选项列表,则可以向 Windows 窗体添加各种列表控件。 常见的列表控件主要有以下几种:
- ComboBox,下拉列表组合框,它显示两个部分:顶部部分是一个文本框,允许用户键入列表项。 第二部分是一个列表框,它显示可以从中选择一个项的列表。
- ListBox,列表框,此控件显示一个列表,可以从中选择一个或多个项。
- CheckedListBox,复选列表框,此控件不仅可以如ListBox 控件一样显示项列表,还可在列表中的项旁边显示复选标记,它是 ListBox 控件的扩展,具备ListBox控件的所有功能。
- ListView,显示带图标的项列表,可以使用此控件创建像Windows资源管理器一样的用户界面,该控件有四种视图模式:LargeIcon、SmallIcon、List 和 Details。
- TreeView,树状结构显示控件,它展示节点的层级结构,树视图中的每个节点可能包含其他节点,称为子节点。 TreeView控件可以将父节点,或包含子节点的节点,显示为展开状态或折叠状态。
上述列表控件既有功能相似之处,也有不同之处,在某些情况下是可以互换的。 但是在另一些场景下,一个可能比另一个更适合某个任务。通常,当有建议的选项时,ComboBox是合适的,当你想要将输入限制为列表上的内容时,ListBox是合适的。此外,ComboBox可节省窗体上的空间,在用户单击向下箭头之前不会显示完整列表,因此组合框可以轻松容纳在较小空间中。
数据构造
在本示例中,为了演示了各个列表控件的使用,先构造数据,本示例采用学校(Shcool),院系(Department),专业(Major),年级(Grade),班级(Class)具备层级关系的模型,模型代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Okcoder.WinForm.Demo
{
/// <summary>
/// 学校
/// </summary>
public class School
{
public int Id { get; set; }
public string Name { get; set; }
public List<Department> Departments { get; set; }
}
/// <summary>
/// 系或学院
/// </summary>
public class Department
{
public int Id { get; set; }
public string Name { get; set; }
public List<Major> Majors { get; set; }
}
/// <summary>
/// 专业
/// </summary>
public class Major
{
public int Id { get; set; }
public string Name { get; set; }
public List<Grade> Grades { get; set; }
}
/// <summary>
/// 年级
/// </summary>
public class Grade
{
public int Id { get; set; }
public string Name { get; set; }
public List<Class> Classes { get; set; }
}
/// <summary>
/// 班级
/// </summary>
public class Class
{
public int Id { get; set; }
public string Name { get; set; }
}
}
创建SqlDalHelper,模拟数据库操作,构造示例数据,如下所示:
namespace Okcoder.WinForm.Demo
{
public class SqlDalHelper
{
private List<School> schools;
private List<Like> likes;
private List<Constellation> constellations;
public SqlDalHelper()
{
InitShcoolList();
InitLikes();
InitConstellations();
}
private void InitShcoolList()
{
string file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "schools.json");
string json = File.ReadAllText(file);
schools = Newtonsoft.Json.JsonConvert.DeserializeObject<List<School>>(json);
}
/// <summary>
/// 查询学校列表
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public List<School> QuerySchools(string name)
{
if (string.IsNullOrEmpty(name))
{
return this.schools;
}
var list = this.schools.Where(item => item.Name.Contains(name)).ToList();
return list;
}
/// <summary>
/// 根据ID获取学校信息
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public School? GetSchool(int id)
{
return schools.FirstOrDefault(item => item.Id == id);
}
}
}
其中schools.json文件为模拟测试数据,具体如下:
[
{
"Id": 1,
"Name": "北京大学",
"Departments": [
{
"Id": 11,
"Name": "计算机系",
"Majors": [
{
"Id": 111,
"Name": "计算机科学与技术",
"Grades": [
{
"Id": 1111,
"Name": "大一",
"Classes": [
{
"Id": 11111,
"Name": "一班"
},
{
"Id": 11112,
"Name": "二班"
},
{
"Id": 11113,
"Name": "三班"
}
]
},
{
"Id": 1112,
"Name": "大二",
"Classes": [
{
"Id": 11121,
"Name": "一班"
},
{
"Id": 11122,
"Name": "二班"
},
{
"Id": 11123,
"Name": "三班"
},
{
"Id": 11124,
"Name": "四班"
}
]
},
{
"Id": 1113,
"Name": "大三",
"Classes": [
{
"Id": 11131,
"Name": "一班"
},
{
"Id": 11132,
"Name": "二班"
}
]
},
{
"Id": 1114,
"Name": "大四",
"Classes": [
{
"Id": 11141,
"Name": "一班"
},
{
"Id": 11142,
"Name": "二班"
}
]
}
]
},
{
"Id": 112,
"Name": "通信电路",
"Grades": [
{
"Id": 1121,
"Name": "大一",
"Classes": [
{
"Id": 11211,
"Name": "一班"
},
{
"Id": 11212,
"Name": "二班"
}
]
},
{
"Id": 1122,
"Name": "大二",
"Classes": [
{
"Id": 11221,
"Name": "一班"
},
{
"Id": 11222,
"Name": "二班"
},
{
"Id": 11223,
"Name": "三班"
}
]
},
{
"Id": 1123,
"Name": "大三",
"Classes": [
{
"Id": 11231,
"Name": "一班"
},
{
"Id": 11232,
"Name": "二班"
}
]
},
{
"Id": 1124,
"Name": "大四",
"Classes": [
{
"Id": 11241,
"Name": "一班"
},
{
"Id": 11242,
"Name": "二班"
}
]
}
]
}
]
},
{
"Id": 12,
"Name": "法学系",
"Majors": [
{
"Id": 121,
"Name": "国内法学",
"Grades": [
{
"Id": 1211,
"Name": "大一",
"Classes": [
{
"Id": 12111,
"Name": "一班"
},
{
"Id": 12112,
"Name": "二班"
},
{
"Id": 12113,
"Name": "三班"
}
]
},
{
"Id": 1212,
"Name": "大二",
"Classes": [
{
"Id": 12121,
"Name": "一班"
},
{
"Id": 12122,
"Name": "二班"
},
{
"Id": 12123,
"Name": "三班"
},
{
"Id": 12124,
"Name": "四班"
}
]
},
{
"Id": 1213,
"Name": "大三",
"Classes": [
{
"Id": 12131,
"Name": "一班"
},
{
"Id": 12132,
"Name": "二班"
}
]
},
{
"Id": 1214,
"Name": "大四",
"Classes": [
{
"Id": 12141,
"Name": "一班"
},
{
"Id": 12142,
"Name": "二班"
}
]
}
]
},
{
"Id": 122,
"Name": "国际法学",
"Grades": [
{
"Id": 1221,
"Name": "大一",
"Classes": [
{
"Id": 12211,
"Name": "一班"
},
{
"Id": 12212,
"Name": "二班"
}
]
},
{
"Id": 1222,
"Name": "大二",
"Classes": [
{
"Id": 12221,
"Name": "一班"
},
{
"Id": 12222,
"Name": "二班"
},
{
"Id": 12223,
"Name": "三班"
}
]
},
{
"Id": 1223,
"Name": "大三",
"Classes": [
{
"Id": 12231,
"Name": "一班"
},
{
"Id": 12232,
"Name": "二班"
}
]
},
{
"Id": 1224,
"Name": "大四",
"Classes": [
{
"Id": 12241,
"Name": "一班"
},
{
"Id": 12242,
"Name": "二班"
}
]
}
]
}
]
}
]
},
{
"Id": 2,
"Name": "清华大学",
"Departments": [
{
"Id": 21,
"Name": "建筑系",
"Majors": [
{
"Id": 211,
"Name": "园林建筑",
"Grades": [
{
"Id": 2111,
"Name": "大一",
"Classes": [
{
"Id": 21111,
"Name": "一班"
},
{
"Id": 21112,
"Name": "二班"
},
{
"Id": 21113,
"Name": "三班"
}
]
},
{
"Id": 2112,
"Name": "大二",
"Classes": [
{
"Id": 21121,
"Name": "一班"
},
{
"Id": 21122,
"Name": "二班"
},
{
"Id": 21123,
"Name": "三班"
},
{
"Id": 21124,
"Name": "四班"
}
]
},
{
"Id": 2113,
"Name": "大三",
"Classes": [
{
"Id": 21131,
"Name": "一班"
},
{
"Id": 21132,
"Name": "二班"
}
]
},
{
"Id": 2114,
"Name": "大四",
"Classes": [
{
"Id": 21141,
"Name": "一班"
},
{
"Id": 21142,
"Name": "二班"
}
]
}
]
},
{
"Id": 212,
"Name": "古建筑",
"Grades": [
{
"Id": 2121,
"Name": "大一",
"Classes": [
{
"Id": 21211,
"Name": "一班"
},
{
"Id": 21212,
"Name": "二班"
}
]
},
{
"Id": 2122,
"Name": "大二",
"Classes": [
{
"Id": 21221,
"Name": "一班"
},
{
"Id": 21222,
"Name": "二班"
},
{
"Id": 21223,
"Name": "三班"
}
]
},
{
"Id": 2123,
"Name": "大三",
"Classes": [
{
"Id": 21231,
"Name": "一班"
},
{
"Id": 21232,
"Name": "二班"
}
]
},
{
"Id": 2124,
"Name": "大四",
"Classes": [
{
"Id": 21241,
"Name": "一班"
},
{
"Id": 21242,
"Name": "二班"
}
]
}
]
}
]
},
{
"Id": 22,
"Name": "文学系",
"Majors": [
{
"Id": 221,
"Name": "近代文学",
"Grades": [
{
"Id": 2211,
"Name": "大一",
"Classes": [
{
"Id": 22111,
"Name": "一班"
},
{
"Id": 22112,
"Name": "二班"
},
{
"Id": 22113,
"Name": "三班"
}
]
},
{
"Id": 2212,
"Name": "大二",
"Classes": [
{
"Id": 22121,
"Name": "一班"
},
{
"Id": 22122,
"Name": "二班"
},
{
"Id": 22123,
"Name": "三班"
},
{
"Id": 22124,
"Name": "四班"
}
]
},
{
"Id": 2213,
"Name": "大三",
"Classes": [
{
"Id": 22131,
"Name": "一班"
},
{
"Id": 22132,
"Name": "二班"
}
]
},
{
"Id": 2214,
"Name": "大四",
"Classes": [
{
"Id": 22141,
"Name": "一班"
},
{
"Id": 22142,
"Name": "二班"
}
]
}
]
},
{
"Id": 222,
"Name": "现代文学",
"Grades": [
{
"Id": 2221,
"Name": "大一",
"Classes": [
{
"Id": 22211,
"Name": "一班"
},
{
"Id": 22212,
"Name": "二班"
}
]
},
{
"Id": 2222,
"Name": "大二",
"Classes": [
{
"Id": 22221,
"Name": "一班"
},
{
"Id": 22222,
"Name": "二班"
},
{
"Id": 22223,
"Name": "三班"
}
]
},
{
"Id": 2223,
"Name": "大三",
"Classes": [
{
"Id": 22231,
"Name": "一班"
},
{
"Id": 22232,
"Name": "二班"
}
]
},
{
"Id": 2224,
"Name": "大四",
"Classes": [
{
"Id": 22241,
"Name": "一班"
},
{
"Id": 22242,
"Name": "二班"
}
]
}
]
}
]
}
]
},
{
"Id": 3,
"Name": "南开大学",
"Departments": [
{
"Id": 31,
"Name": "体育系",
"Majors": [
{
"Id": 311,
"Name": "乒乓球",
"Grades": [
{
"Id": 3111,
"Name": "大一",
"Classes": [
{
"Id": 31111,
"Name": "一班"
},
{
"Id": 31112,
"Name": "二班"
},
{
"Id": 31113,
"Name": "三班"
}
]
},
{
"Id": 3112,
"Name": "大二",
"Classes": [
{
"Id": 31121,
"Name": "一班"
},
{
"Id": 31122,
"Name": "二班"
},
{
"Id": 31123,
"Name": "三班"
},
{
"Id": 31124,
"Name": "四班"
}
]
},
{
"Id": 3113,
"Name": "大三",
"Classes": [
{
"Id": 31131,
"Name": "一班"
},
{
"Id": 31132,
"Name": "二班"
}
]
},
{
"Id": 3114,
"Name": "大四",
"Classes": [
{
"Id": 31141,
"Name": "一班"
},
{
"Id": 31142,
"Name": "二班"
}
]
}
]
},
{
"Id": 312,
"Name": "篮球",
"Grades": [
{
"Id": 3121,
"Name": "大一",
"Classes": [
{
"Id": 31211,
"Name": "一班"
},
{
"Id": 31212,
"Name": "二班"
}
]
},
{
"Id": 3122,
"Name": "大二",
"Classes": [
{
"Id": 31221,
"Name": "一班"
},
{
"Id": 31222,
"Name": "二班"
},
{
"Id": 31223,
"Name": "三班"
}
]
},
{
"Id": 3123,
"Name": "大三",
"Classes": [
{
"Id": 31231,
"Name": "一班"
},
{
"Id": 31232,
"Name": "二班"
}
]
},
{
"Id": 3124,
"Name": "大四",
"Classes": [
{
"Id": 31241,
"Name": "一班"
},
{
"Id": 31242,
"Name": "二班"
}
]
}
]
}
]
},
{
"Id": 32,
"Name": "电气学院",
"Majors": [
{
"Id": 321,
"Name": "弱电",
"Grades": [
{
"Id": 2211,
"Name": "大一",
"Classes": [
{
"Id": 22111,
"Name": "一班"
},
{
"Id": 22112,
"Name": "二班"
},
{
"Id": 22113,
"Name": "三班"
}
]
},
{
"Id": 2212,
"Name": "大二",
"Classes": [
{
"Id": 22121,
"Name": "一班"
},
{
"Id": 22122,
"Name": "二班"
},
{
"Id": 22123,
"Name": "三班"
},
{
"Id": 22124,
"Name": "四班"
}
]
},
{
"Id": 2213,
"Name": "大三",
"Classes": [
{
"Id": 22131,
"Name": "一班"
},
{
"Id": 22132,
"Name": "二班"
}
]
},
{
"Id": 2214,
"Name": "大四",
"Classes": [
{
"Id": 22141,
"Name": "一班"
},
{
"Id": 22142,
"Name": "二班"
}
]
}
]
},
{
"Id": 322,
"Name": "强电",
"Grades": [
{
"Id": 3221,
"Name": "大一",
"Classes": [
{
"Id": 32211,
"Name": "一班"
},
{
"Id": 32212,
"Name": "二班"
}
]
},
{
"Id": 3222,
"Name": "大二",
"Classes": [
{
"Id": 32221,
"Name": "一班"
},
{
"Id": 32222,
"Name": "二班"
},
{
"Id": 32223,
"Name": "三班"
}
]
},
{
"Id": 3223,
"Name": "大三",
"Classes": [
{
"Id": 32231,
"Name": "一班"
},
{
"Id": 32232,
"Name": "二班"
}
]
},
{
"Id": 3224,
"Name": "大四",
"Classes": [
{
"Id": 32241,
"Name": "一班"
},
{
"Id": 32242,
"Name": "二班"
}
]
}
]
}
]
}
]
}
]
ComboBox
ComboBox用于在下拉列表组合框中显示数据,默认情况下,ComboBox 控件显示两个部分:顶部部分是一个文本框,允许用户键入列表项。 第二部分是一个列表框,当点击右侧的下拉箭头时,显示用户可以从中选择一个项的列表。
ComboBox控件的关键属性:
- SelectedIndex,表示控件当前选中项的索引,它是一个int类型的值,还可以通过在代码中更改 SelectedIndex 值,以编程方式变更ComboBox控件的选择项。 如果未选择任何项,则 SelectedIndex 值为 -1。 如果选择列表中的第一项,则 SelectedIndex 值为 0。
- SelectedItem,表示控件当前选择的项,此属性类似于 SelectedIndex,但返回项本身(通常是字符串值)。
- Count,表示控件中Items列表项的数量,Count 属性的值始终比最大可能的 SelectedIndex 值大 1,因为 SelectedIndex 是从零开始计数的。
- Items,表示列表控件包含的列表项集合,可以通过Items属性Add,Remove,RemoveAt,Clear等方法修改Items中值的内容。
- DataSource,表示ComboBox控件的数据源,它是一个可空的object类型,接收实现IList接口或Array类型的数据。
- DisplayMember,表示列表控件需要显示的内容,它通常是绑定的Item项的属性名称或列名。
- ValueMember,表示列表控件的真实Value应的值,它通常是绑定的Item项的属性名称或列名。
ComboBox控件的关键事件:
- SelectedIndexChanged,当ComboxBox控件的选择项发生改变时触发,可以用来响应ComboBox的选择项改变。
说明,ComboBox下拉列表组合框控件可以通过Items属性来添加或删除列表框中的值,也可以通过统一设置数据源(DataSource)方式进行的赋值。
接下来在Form表单的Load方法中,采用DataSource的方式进行赋值,首先通过sqlDalHelper实例的QuerySchools方法获取学校列表,在将ComboBox控件的DataSource属性赋值为schools列表,由于列表中的项是School对象,所以需要通过DisplayMember指定需要显示的属性路径,ValueMember指定真实的Value的属性路径。具体如下所示:
var schools = sqlDalHelper.QuerySchools(string.Empty);
this.combSchools.DataSource = schools.ToList();
this.combSchools.DisplayMember = "Name";
this.combSchools.ValueMember = "Id";
运行程序,如下所示:

ListBox
ListBox控件显示一个列表,用户可以从中选择一个或多个项。 如果列表项总数超过可显示的数量,则会自动向 ListBox 控件添加滚动条。ListBox控件的关键属性:
- MultiColumn,表示是否在列表框中显示多列,当属性 MultiColumn 设置为
true时,如果列表项总数超过可显示的数量时,列表框将显示为多列,并显示水平滚动条。 当MultiColumn 属性设置为false时,如果列表项总数超过可显示的数量时,列表框显示为单列,并出现垂直滚动条。 - ScrollAlwaysVisible,表示滚动条是否一直显示,如果 ScrollAlwaysVisible 设置为
true,则无论项数如何,滚动条都会显示,默认为false。 - SelectionMode,表示一次可以选择多少个列表项,它是一个枚举类型:None表示不可以选择,One 表示一此只能选择一个,MultiSimple表示一次可以选择多个项,MultiExtended表示一次可以选择多个,且可以使用组合键盘,如Shift,Ctrl帮助选择。
- 与ComboBox控件一样,ListBox控件同样具备SelectedIndex,SelectedItem,Count,Items,DataSource,DisplayMember,ValueMember等属性。
ListBox控件的关键事件:
- SelectedIndexChanged,与ComboBox控件一样,ListBox同样具备SelectedIndexChanged事件,用来响应ListBox控件的选择项改变。
同样在Form表单的Load方法中,采用DataSource的方式进行赋值,首先通过sqlDalHelper实例的QuerySchools方法获取学校列表,在将ComboBox控件的DataSource属性赋值为schools列表,由于列表中的项是School对象,所以需要通过DisplayMember指定需要显示的属性路径,ValueMember指定真实的Value的属性路径。具体如下所示:
lbShcools.DataSource = schools.ToList();
lbShcools.DisplayMember = "Name";
lbShcools.ValueMember = "Id";
lbShcools.MultiColumn = false;
当用户选择ListBox中的项时,会触发SelectedIndexChanged,可以用来确定用户选择的项,如下所示:
private void lbShcools_SelectedIndexChanged(object sender, EventArgs e)
{
if (lbShcools.SelectedItems != null)
{
List<string> schools = new List<string>();
foreach (var item in this.lbShcools.SelectedItems)
{
var school = item as School;
if (school != null)
{
schools.Add(school.Name);
}
}
this.lblSchools.Text = string.Join(",\n", schools);
}
}
运行程序,如下所示:
CheckedListBox
CheckedListBox控件是 ListBox 控件的扩展,它不仅可以显示项列表(如 ListBox 控件),还可在列表中的项旁边显示复选标记。CheckedListBox控件几乎执行ListBox(列表框)执行的所有操作, 两个控件之间的其他差异是,CheckedListBox仅支持 DrawMode.Normal;并且Checked ListBox只能选择一个项目或无项。CheckedListBox可以在设计时使用 字符串集合编辑器 添加项,也可以在运行时使用 Items 属性从集合中动态添加项。
CheckedListBox控件的关键属性:
- CheckedItems,表示选中的项集合,通过遍历可以获取所有被选中的项。也可以通过控件的GetItemChecked 方法来获取项是否被选中,参数为项索引号,返回值true表示被选中,false表示未被选中。
- CheckOnClick,表示当用户点击列表中的项时,列表项的复选框是否改变状态,默认为false:需要先选择项,再点击复选框进行选择。如果设置为true,则点击列表项会同时改变复选框的状态。
- 与ListBox控件一样,CheckedListBox控件同样具备SelectedIndex,SelectedItem,Count,Items,DataSource,DisplayMember,ValueMember,MultiColumn,ColumnWidth等属性。
CheckedListBox控件的关键事件:
- ItemCheck,当CheckedListBox控件的项的复选框的状态发送变化时触发,事件参数ItemCheckEventArgs,包括列表项复选框的前(CurrentValue),后(NewValue)状态,以及项索引(Index)。
说明:Checked和Selected效果不一样,Checked是复选框被选中,Selected是确定已突出显示哪些项。所以CheckedItems和SelectedItems是表示不同的含义。
本示例构造个人爱好列表框,用户可以勾选个人爱好,首先创建Like模型,如下所示:
namespace Okcoder.WinForm.Demo
{
public class Like
{
public int Id { get; set; }
public string Name { get; set; }
}
}
在SqlDalHelper类中初始化个人爱好列表,并增加QueryLikes接口获取爱好列表,如下所示:
private void InitLikes()
{
likes = new List<Like>();
likes.Add(new Like()
{
Id = 1,
Name = "足球",
});
likes.Add(new Like()
{
Id = 2,
Name = "篮球",
});
likes.Add(new Like()
{
Id = 3,
Name = "乒乓球",
});
likes.Add(new Like()
{
Id = 4,
Name = "跳舞",
});
likes.Add(new Like()
{
Id = 5,
Name = "唱歌",
});
}
public List<Like> QueryLikes()
{
return this.likes;
}
在Form表单的Load方法中,获取Like列表,并给CheckListBox赋值,如下所示:
var likes = sqlDalHelper.QueryLikes();
this.chklbLikes.DataSource = likes;
this.chklbLikes.DisplayMember = "Name";
this.chklbLikes.MultiColumn = true;
this.chklbLikes.ColumnWidth = 80;
this.chklbLikes.CheckOnClick = true;
在上述示例中,设置了MultiColumn为true,如果一列无法显示时,为显示为多列。运行效果,如下所示:

注册CheckedListBox控件的ItemCheck事件,可以获取用户选中的项,如下所示:
private void chklbLikes_ItemCheck(object sender, ItemCheckEventArgs e)
{
List<string> likes = new List<string>();
foreach (var item in this.chklbLikes.CheckedItems)
{
var like = item as Like;
if (like != null)
{
likes.Add(like.Name);
}
}
//因为ItemCheck方法具有滞后性,是等事件发生后,状态才会更新,所以判断NewValue的值,提前获取。
if (e.NewValue == CheckState.Checked)
{
var like = this.chklbLikes.Items[e.Index] as Like;
if (like != null)
{
likes.Add(like.Name);
}
}
if(e.NewValue==CheckState.Unchecked)
{
var like = this.chklbLikes.Items[e.Index] as Like;
if (like != null)
{
if (likes.Contains(like.Name))
{
likes.Remove(like.Name);
}
}
}
this.lblLikes.Text = string.Join(",", likes);
}
TreeView
TreeView控件展示节点的层级结构,就像在 Windows 操作系统中 Windows 资源管理器功能左侧窗格中显示文件和文件夹一样。树视图中的每个节点可能包含其他节点,称为子节点。 可以将父节点,或包含子节点的节点,显示为展开状态或折叠状态。
TreeView控件的关键属性:
- CheckBoxes,是否在树视图控件中的树节点旁边显示复选框,可以将TreeView中节点的Checked属性设置为true或false进行动态的选择或取消。
- Nodes,获取TreeView的节点集合或子节点集合。
- SelectedNode 属性获取或设置当前选定的节点,通过SelectedNode属性的Nodes属性的Add/Remove方法,可以动态的为当前选择节点添加/删除子节点。
- ImageList,树状列表中节点图像集合,可以通过指定Node节点的ImageIndex属性为树视图中的节点设置正常状态下的默认图像,SelectedImageIndex设置选择状态下的图像。
- Clear方法可以为节点清除所有子节点。如果是TreeView的Clear方法,则清除所有节点;如果是当前选择的节点调用Clear方法,则清除选定节点的子节点。
- FirstNode,获取节点的第一个子节点,LastNode,获取节点的最后一个子节点。
- NextNode,获取节点的下一个同级节点,PrevNode,获取节点的上一个同级节点。
- Parent,获取节点的父级节点。
- TopNode,TreeView控件的根节点。
TreeView控件的关键事件:
- AfterSelect,当TreeView的节点被Select时触发此事件,可以用来确定用户点击了哪个节点。
- AfterCheck,当TreeView控件中的节点显示CheckBox且被选中时触发。
在本示例中,当用户选择学校时,会在右侧显示选择学校的详细信息,所以需要在ComboBox的SelectedIndexChanged事件中处理TreeView节点的初始化,如下所示:
private void combSchools_SelectedIndexChanged(object sender, EventArgs e)
{
//var id = combSchools.SelectedValue;//获取Id
this.tvSchool.Nodes.Clear();
var school = combSchools.SelectedItem as School;
if (school != null)
{
this.lblSchool.Text = school.Name;
TreeNode nodeSchool = new TreeNode();
nodeSchool.Text = school.Name;
for (int i = 0; i < school.Departments.Count; i++)
{
var department = school.Departments[i];
TreeNode nodeDepartment = new TreeNode();
nodeDepartment.Text = department.Name;
for (int j = 0; j < department.Majors.Count; j++)
{
var major = department.Majors[j];
TreeNode nodeMajor = new TreeNode();
nodeMajor.Text = major.Name;
for (int k = 0; k < major.Grades.Count; k++)
{
var grade = major.Grades[k];
TreeNode nodeGrade = new TreeNode();
nodeGrade.Text = grade.Name;
for (int l = 0; l < grade.Classes.Count; l++)
{
var cla = grade.Classes[l];
TreeNode nodeClass = new TreeNode();
nodeClass.Text = cla.Name;
nodeGrade.Nodes.Add(nodeClass);
}
nodeMajor.Nodes.Add(nodeGrade);
}
nodeDepartment.Nodes.Add(nodeMajor);
}
nodeSchool.Nodes.Add(nodeDepartment);
}
this.tvSchool.Nodes.Add(nodeSchool);
}
}
运行程序,示例效果如下:

ListView
ListView控件显示带图标的项列表,可以使用ListView创建用户界面,例如 Windows 资源管理器的右窗格。 通过View 属性可以设置ListView的视图模式,共有四种视图模式:
- LargeIcon 模式显示项文本旁边的大图标,如果控件足够大,则这些项会显示在多个列中。
- SmallIcon 模式相同,只不过它显示小图标。
- List模式显示小图标,但始终位于单个列中。
- Details模式显示多个列中的项。
ListView控件的关键属性:
- Items,包含控件显示的项。
- SelectedItems 属性包含控件中当前选定的项的集合。
- MultiSelect,标识用户可以选择多个项。
- CheckBoxes,是否在ListView控件中的项旁边显示复选框,可以将ListView中项的Checked属性设置为true或false进行动态的选择或取消。
ListView控件的关键事件:
- SelectedIndexChanged,与ComboBox,ListBox控件一样,ListView同样具备SelectedIndexChanged事件,用来响应ListView控件的选择项改变。
本示例采用星座列表图片,首先构造星座模型,如下所示:
namespace Okcoder.WinForm.Demo
{
/// <summary>
/// 星座
/// </summary>
public class Constellation
{
public int Id { get; set; }
public string Name { get; set; }
public string Nick { get; set; }
public string Desc { get; set; }
public int ImgIndex { get; set; }
}
}
接下来在SqlDalHelper中构造星座数据,如下所示:
private void InitConstellations()
{
constellations = new List<Constellation>();
constellations.Add(new Constellation() { Id = 1, Name = "Aries", Nick = "白羊座", Desc = "03-21至04-19", ImgIndex=0 });
constellations.Add(new Constellation() { Id = 2, Name = "Taurus", Nick = "金牛座", Desc = "04-20至05-20", ImgIndex = 1 });
constellations.Add(new Constellation() { Id = 3, Name = "Gemini", Nick = "双子座", Desc = "05-21至06-21", ImgIndex = 2 });
constellations.Add(new Constellation() { Id = 4, Name = "Cancer", Nick = "巨蟹座", Desc = "06-22至07-22", ImgIndex = 3 });
constellations.Add(new Constellation() { Id = 5, Name = "Leo", Nick = "狮子座", Desc = "07-23至08-22", ImgIndex = 4 });
constellations.Add(new Constellation() { Id = 6, Name = "Virgo", Nick = "处女座", Desc = "08-23至09-22", ImgIndex = 5 });
constellations.Add(new Constellation() { Id = 7, Name = "Libra", Nick = "天秤座", Desc = "09-23至10-23", ImgIndex = 6 });
constellations.Add(new Constellation() { Id = 8, Name = "Scorpio", Nick = "天蝎座", Desc = "10-24至11-22", ImgIndex = 7 });
constellations.Add(new Constellation() { Id = 9, Name = "Sagittarius", Nick = "射手座", Desc = "11-23至12-21", ImgIndex = 8 });
constellations.Add(new Constellation() { Id = 10, Name = "Capricorn", Nick = "摩羯座", Desc = "12-22至01-19", ImgIndex = 9 });
constellations.Add(new Constellation() { Id = 11, Name = "Aquarius", Nick = "水瓶座", Desc = "01-20至01-18", ImgIndex = 10 });
constellations.Add(new Constellation() { Id = 12, Name = "Pisces", Nick = "双鱼座", Desc = "02-19至03-20", ImgIndex = 11 });
}
public List<Constellation> QueryConstellations()
{
return this.constellations;
}
在Form表单的Load事件中,获取列表并赋值给ListView控件,如下所示:
private void FrmList2_Load(object sender, EventArgs e)
{
//1.先获取图像,初始化ImageList列表
var images = Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Constellation"));
images = images.OrderBy(item => item).ToArray();//排序
foreach (var image in images)
{
this.imgList.Images.Add(Image.FromFile(image));
}
this.imgList.ImageSize = new Size(100, 100);
//2.绑定ListView
this.lvConstellations.LargeImageList = this.imgList;
this.lvConstellations.MultiSelect = false;
this.lvConstellations.View = View.LargeIcon;
//3.初始化ListView中的Items项
var constellations = sqlDalHelper.QueryConstellations();
if (constellations.Count > 0)
{
foreach (var constellation in constellations)
{
this.lvConstellations.Items.Add(new ListViewItem(constellation.Nick, constellation.ImgIndex));
}
}
//如果3,1,2的顺序可能会导致ListView中的图像不显示。
}
当ListView控件选择时,显示星座的大图和详细信息,如下所示:
private void lvConstellations_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.lvConstellations.SelectedIndices.Count < 1)
{
return;
}
int index = this.lvConstellations.SelectedIndices[0];
var constellation = this.sqlDalHelper.QueryConstellations()[index];
if (constellation != null)
{
this.lblName.Text = constellation.Name;
this.lblNick.Text = constellation.Nick;
this.lblDesc.Text = constellation.Desc;
this.pictureBox1.Image = this.imgList.Images[constellation.ImgIndex];
this.pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
}
}
其中星座图片从网上下载完成后,放在程序根目录下,如下所示:

运行程序,如下所示:

以上就是《基于.NET的Windows窗体编程之WinForms列表控件》的全部内容,旨在抛砖引玉,一起学习,共同进步。
文章摘自:https://www.cnblogs.com/hsiang/p/19964614
