列 表 控 件 列表控件 列表控件
列表控件ListView
相当于ListBox的增强版,支持多列显示
典型例子:Windows的文件管理器的列表显示
列表控件的几种视图:
Detail:详情模式
List:列表模式
LargeIcon:大图标模式
SmallIcon :小图标模式
1.列表控件
列表控件的几个特点:
- 显示模式
- 可以切换
- 可以多字段显示
- 可以设置图标标签
- 可以编辑
- 每列可以单独排序
示例:添加一个ListView
- 设置显示模式
- 设置列标题
- 添加数据项
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinForm列表控件
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
InitListView();
}
private void InitListView()
{
// 设置显示模式
listView1.View = View.Details;
// 整行选中
listView1.FullRowSelect = true;
// 设置列名
// 宽度值-2表示自动调整宽度
listView1.Columns.Add("文件名", -2, HorizontalAlignment.Left);
listView1.Columns.Add("修改时期", 150, HorizontalAlignment.Left);
listView1.Columns.Add("类型", 100, HorizontalAlignment.Left);
listView1.Columns.Add("大小", -2, HorizontalAlignment.Left);
// 添加数据项
ListViewItem item1 = new ListViewItem("major.jpg", 0);
// 设置子项数据
item1.SubItems.Add("2020-12-22 9:37");
item1.SubItems.Add("jpg");
item1.SubItems.Add("888 KB");
listView1.Items.Add(item1);
}
}
}
2.添加数据
图标设置:
listView1.LargeImageList
用于大图标模式
listView1.SmallImageList
用于其他显示模式
在添加一项时,指定所使用的图片的索引
item = new ListViewItem(label, imageIndex)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinForm列表控件
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
InitListView();
// 列出E盘下的所有项
LoadDir(new DirectoryInfo("E:\\"));
}
private void InitListView()
{
// 设置显示模式
listView1.View = View.Details;
// 整行选中
listView1.FullRowSelect = true;
// 设置列名
// 宽度值-2表示自动调整宽度
listView1.Columns.Add("文件名", -2, HorizontalAlignment.Left);
listView1.Columns.Add("修改时期", 150, HorizontalAlignment.Left);
listView1.Columns.Add("类型", 100, HorizontalAlignment.Left);
listView1.Columns.Add("大小", -2, HorizontalAlignment.Left);
// 创建ImageList,并添加2个小图标
ImageList imageList = new ImageList();
imageList.ImageSize = new Size(16, 16);
imageList.Images.Add(Properties.Resources.Ico_Folder);
imageList.Images.Add(Properties.Resources.Ico_File);
// 设置 SmallImageList 用于显示
listView1.SmallImageList = imageList;
}
private void LoadDir(DirectoryInfo dir)
{
listView1.BeginUpdate();
// 子目录
DirectoryInfo[] subDirs = dir.GetDirectories();
foreach (DirectoryInfo d in subDirs)
{
if ((d.Attributes & FileAttributes.Hidden) > 0) continue;
AddListItem(d.Name, d.LastWriteTime, "文件夹", -1);
}
// 子文件
FileInfo[] subFiles = dir.GetFiles();
foreach (FileInfo f in subFiles)
{
if ((f.Attributes & FileAttributes.Hidden) > 0) continue;
string ext = f.Extension.ToUpper(); // 后缀
AddListItem(f.Name, f.LastWriteTime, ext, f.Length);
}
listView1.EndUpdate();
}
private void AddListItem(string label
, DateTime time
, string type
, long size)
{
// 判断是文件还是文件夹,使用不同的图标
int imageIndex = 0;
if (!type.Equals("文件夹")) imageIndex = 1;
ListViewItem item
= new ListViewItem(label, imageIndex);
// 时间
item.SubItems.Add(time.ToString("yyyy-MM-dd HH:mm"));
// 类型
item.SubItems.Add(type);
// 文件大小
string sizeStr = "";
if (size < 0)
sizeStr = ""; // 文件夹不显示大小
else if (size < 1000)
sizeStr = "" + size;
else if (size < 1000000)
sizeStr = size / 1000 + " KB";
else if (size < 1000000000)
sizeStr = size / 1000000 + " MB";
else
sizeStr = size / 1000000000 + " GB";
item.SubItems.Add(sizeStr);
listView1.Items.Add(item);
}
}
}
3.切换显示模式
添加右键菜单,实现4种显示模式的切换
- 设置大图标列表
- 添加右键菜单
添加4个菜单项
添加菜单项的点击处理 - 添加右键处理
点击右键时,弹出菜单
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
InitListView();
// 列出C盘下的所有项
LoadDir(new DirectoryInfo("c:\\"));
}
private void InitListView()
{
// 设置显示模式
listView1.View = View.Details;
// 整行选中
listView1.FullRowSelect = true;
// 设置列名
// 宽度值-2表示自动调整宽度
listView1.Columns.Add("文件名", -2, HorizontalAlignment.Left);
listView1.Columns.Add("修改时期", 150, HorizontalAlignment.Left);
listView1.Columns.Add("类型", 100, HorizontalAlignment.Left);
listView1.Columns.Add("大小", -2, HorizontalAlignment.Left);
// 设置小图标列表
ImageList imageList = new ImageList();
imageList.ImageSize = new Size(16, 16);
imageList.Images.Add(Properties.Resources.Ico_Folder);
imageList.Images.Add(Properties.Resources.Ico_File);
// 设置 SmallImageList 用于显示
listView1.SmallImageList = imageList;
// 设置大图标列表
ImageList imageList2 = new ImageList();
imageList2.ImageSize = new Size(64, 64);
imageList2.Images.Add(Properties.Resources.Ico_Folder2);
imageList2.Images.Add(Properties.Resources.Ico_File2);
// 设置 SmallImageList 用于显示
listView1.LargeImageList = imageList2;
}
private void LoadDir(DirectoryInfo dir)
{
// listView1.BeginUpdate();
// 子目录
DirectoryInfo[] subDirs = dir.GetDirectories();
foreach (DirectoryInfo d in subDirs)
{
if ((d.Attributes & FileAttributes.Hidden) > 0) continue;
AddListItem(d.Name, d.LastWriteTime, "文件夹", -1);
}
// 子文件
FileInfo[] subFiles = dir.GetFiles();
foreach (FileInfo f in subFiles)
{
if ((f.Attributes & FileAttributes.Hidden) > 0) continue;
string ext = f.Extension.ToUpper(); // 后缀
AddListItem(f.Name, f.LastWriteTime, ext, f.Length);
}
// listView1.EndUpdate();
}
private void AddListItem(string label
, DateTime time
, string type
, long size)
{
// 判断是文件还是文件夹,使用不同的图标
int imageIndex = 0;
if (!type.Equals("文件夹")) imageIndex = 1;
ListViewItem item
= new ListViewItem(label, imageIndex);
// 时间
item.SubItems.Add(time.ToString("yyyy-MM-dd HH:mm"));
// 类型
item.SubItems.Add(type);
// 文件大小
string sizeStr = "";
if (size < 0)
sizeStr = ""; // 文件夹不显示大小
else if (size < 1000)
sizeStr = "" + size;
else if (size < 1000000)
sizeStr = size / 1000 + " KB";
else if (size < 1000000000)
sizeStr = size / 1000000 + " MB";
else
sizeStr = size / 1000000000 + " GB";
item.SubItems.Add(sizeStr);
listView1.Items.Add(item);
}
private void listView1_MouseUp(object sender, MouseEventArgs e)
{
if(e.Button == MouseButtons.Right)
{
ListViewItem item = listView1.GetItemAt(e.X, e.Y);
// 根据当前的显示模式,设置菜单项的状态
View view = listView1.View;
menuViewDetail.Checked = (view == View.Details);
menuViewList.Checked = (view == View.List);
menuViewLargeIcon.Checked = (view == View.LargeIcon);
menuViewSmallIcon.Checked = (view == View.SmallIcon);
contextMenu.Show(listView1, e.Location);
}
}
// 菜单项的点击处理
private void menuViewDetail_Click(object sender, EventArgs e)
{
listView1.View = View.Details;
}
private void menuViewList_Click(object sender, EventArgs e)
{
listView1.View = View.List ;
}
private void menuViewLargeIcon_Click(object sender, EventArgs e)
{
listView1.View = View.LargeIcon;
}
private void menuViewSmallIcon_Click(object sender, EventArgs e)
{
listView1.View = View.SmallIcon;
}
4.列的排序
public partial class Form1 : Form
{
// 当前排序
private bool asc = true;
public Form1()
{
InitializeComponent();
InitListView();
// 列出C盘下的所有项
LoadDir(new DirectoryInfo("c:\\"));
}
private void InitListView()
{
// 设置显示模式
listView1.View = View.Details;
// 整行选中
listView1.FullRowSelect = true;
// 设置列名
// 宽度值-2表示自动调整宽度
listView1.Columns.Add("文件名", -2, HorizontalAlignment.Left);
listView1.Columns.Add("修改时期", 150, HorizontalAlignment.Left);
listView1.Columns.Add("类型", 100, HorizontalAlignment.Left);
listView1.Columns.Add("大小", -2, HorizontalAlignment.Left);
// 设置小图标列表
ImageList imageList = new ImageList();
imageList.ImageSize = new Size(16, 16);
imageList.Images.Add(Properties.Resources.Ico_Folder);
imageList.Images.Add(Properties.Resources.Ico_File);
// 设置 SmallImageList 用于显示
listView1.SmallImageList = imageList;
// 设置大图标列表
ImageList imageList2 = new ImageList();
imageList2.ImageSize = new Size(64, 64);
imageList2.Images.Add(Properties.Resources.Ico_Folder2);
imageList2.Images.Add(Properties.Resources.Ico_File2);
// 设置 SmallImageList 用于显示
listView1.LargeImageList = imageList2;
// 点击列标题时,指示排序的图标
// 把图标资源加到 SmallImageList 里,供列标题头部显示
imageList.Images.Add("Sort_ASC", Properties.Resources.Ico_Up);
imageList.Images.Add("Sort_DESC", Properties.Resources.Ico_Down);
listView1.Columns[0].ImageKey = "Sort_ASC";
}
private void LoadDir(DirectoryInfo dir)
{
// listView1.BeginUpdate();
// 子目录
DirectoryInfo[] subDirs = dir.GetDirectories();
foreach (DirectoryInfo d in subDirs)
{
if ((d.Attributes & FileAttributes.Hidden) > 0) continue;
MyListItemTag tag = new MyListItemTag();
tag.path = d.FullName;
tag.name = d.Name;
tag.time = d.LastWriteTime;
tag.type = 0;
tag.size = -1;
tag.ext = "文件夹";
AddListItem(tag);
}
// 子文件
FileInfo[] subFiles = dir.GetFiles();
foreach (FileInfo f in subFiles)
{
if ((f.Attributes & FileAttributes.Hidden) > 0) continue;
MyListItemTag tag = new MyListItemTag();
tag.path = f.FullName;
tag.name = f.Name;
tag.time = f.LastWriteTime;
tag.type = 1;
tag.size = f.Length;
tag.ext = f.Extension.ToUpper();
AddListItem(tag);
}
// listView1.EndUpdate();
}
private void AddListItem(MyListItemTag tag)
{
// 判断是文件还是文件夹,使用不同的图标
int imageIndex = 0;
if (tag.type == 1) imageIndex = 1;
ListViewItem item = new ListViewItem(tag.name, imageIndex);
item.Tag = tag;
// 时间
item.SubItems.Add(tag.time.ToString("yyyy-MM-dd HH:mm"));
// 类型
item.SubItems.Add(tag.ext);
// 文件大小
long size = tag.size;
string sizeStr = "";
if (size < 0)
sizeStr = ""; // 文件夹不显示大小
else if (size < 1000)
sizeStr = "" + size;
else if (size < 1000000)
sizeStr = size / 1000 + " KB";
else if (size < 1000000000)
sizeStr = size / 1000000 + " MB";
else
sizeStr = size / 1000000000 + " GB";
item.SubItems.Add(sizeStr);
listView1.Items.Add(item);
}
private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
{
if(e.Column == 0)
{
this.asc = !asc;
if(asc)
{
listView1.ListViewItemSorter = new MyListItemSorter(true);
listView1.Sort();
listView1.Columns[0].ImageKey = "Sort_ASC";
}
else
{
listView1.ListViewItemSorter = new MyListItemSorter(false);
listView1.Sort();
listView1.Columns[0].ImageKey = "Sort_DESC";
}
}
}
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
public class MyListItemSorter : IComparer
{
public bool asc = true;
public MyListItemSorter(bool asc)
{
this.asc = asc;
}
public int Compare(object x, object y)
{
ListViewItem item1 = x as ListViewItem;
ListViewItem item2 = (ListViewItem)y;
// Tag: 每一项关联的数据
MyListItemTag tag1 = (MyListItemTag)item1.Tag;
MyListItemTag tag2 = (MyListItemTag)item2.Tag;
// 目录在前, 文件在后
if (tag1.type != tag2.type)
return CompareInt(true, tag1.type, tag2.type);
// 按名字比较
return CompareStringIgnoreCase(asc, tag1.name, tag2.name);
}
// 两个 Bool 值的比较
public int CompareBool(bool asc, bool x, bool y)
{
int xx = x ? 1 : 0;
int yy = y ? 1 : 0;
return CompareInt(asc, xx, yy);
}
// 两个 Int 值的比较
public int CompareInt(bool asc, int x, int y)
{
if (asc)
return x - y;
else
return y - x;
}
// 两个String值的比较
public int CompareString(bool asc, string x, string y)
{
if (asc)
return x.CompareTo(y);
else
return y.CompareTo(x);
}
// 两个String值的比较 (不区分大小写)
public int CompareStringIgnoreCase(bool asc, string x, string y)
{
return CompareString(asc, x.ToLower(), y.ToLower());
}
}
// 每个列表项关联的数据
class MyListItemTag
{
public int type = 0; //0, 目录;1 ,谁的
public string path;
public string name;
public DateTime time;
public long size = -1;
public string ext;
}
5.编辑标签
标签Label :指每一个列表项的显示文本
实例:列表项的标签可以被直接编辑
步骤:
- 1设置LabelEdit为true,允许编辑
- 2启动编辑
鼠标先选中、再点击即可启动编辑
也可以调用ListViewItem.BeginEdit()启动编辑
public partial class Form1 : Form
{
// 当前鼠标事件点中的项
private ListViewItem mouseClickItem;
public Form1()
{
InitializeComponent();
InitListView();
// 添加几项数据
AddListItem(new Student(20201001, "shao", "13810012345"));
AddListItem(new Student(20201002, "wang", "18799122300"));
AddListItem(new Student(20201003, "li", "13490912322"));
}
private void InitListView()
{
// 设置显示模式
listView1.View = View.Details;
// 整行选中
// listView1.FullRowSelect = true;
listView1.LabelEdit = true;
// 设置列名
// 宽度值-2表示自动调整宽度
listView1.Columns.Add("姓名", 150, HorizontalAlignment.Left);
listView1.Columns.Add("学号", 150, HorizontalAlignment.Left);
listView1.Columns.Add("手机号", -2, HorizontalAlignment.Left);
}
private void AddListItem(Student stu)
{
ListViewItem item = new ListViewItem(stu.Name, 0);
item.Tag = stu;
item.SubItems.Add(stu.Id + "");
item.SubItems.Add(stu.Phone);
listView1.Items.Add(item);
}
// 鼠标右键点击,弹出菜单
private void listView1_MouseUp(object sender, MouseEventArgs e)
{
if(e.Button == MouseButtons.Right)
{
ListViewItem item = listView1.GetItemAt(e.X, e.Y);
this.mouseClickItem = item;
menu_Rename.Enabled = (item != null);
contextMenuStrip1.Show(listView1, e.Location);
}
}
// 点击 '重命名' 菜单
private void menu_Rename_Click(object sender, EventArgs e)
{
this.mouseClickItem.BeginEdit();
}
// 开启列表项的编辑
private void listView1_BeforeLabelEdit(object sender, LabelEditEventArgs e)
{
}
// 结束列表项的编辑
private void listView1_AfterLabelEdit(object sender, LabelEditEventArgs e)
{
int index = e.Item; // 当前项的索引
string label = e.Label; // 新输入的文本
// 检查是否冲突
for (int i = 0; i < listView1.Items.Count; i++)
{
if (index == i) continue;
if (label == listView1.Items[i].Text)
{
e.CancelEdit = true;
MessageBox.Show("名字重复", "提示");
return;
}
}
e.CancelEdit = false; // 接受此输入
// 更新后台数据
Student stu = (Student)listView1.Items[index].Tag;
stu.Name = label;
}
}
class Student
{
public int Id { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
public Student()
{
}
public Student(int id,string name, string phone)
{
this.Id = id;
this.Name = name;
this.Phone = phone;
}
}