基于.NET的Windows窗体编程之WinForms列表控件


在实际应用中,列表控件主要用于显示列表格式的数据,然后供用户选择,常见的列表控件有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