还在为复杂的数据列表展示而头疼吗?每次需要显示表格数据时都要重新造轮子?作为WinForms开发中的核心控件,ListView不仅能优雅地处理各种列表展示需求,更是构建专业用户界面的基石。
许多C#开发者在使用ListView时往往停留在基础应用层面,错失了它的强大功能。本文将从实战角度出发,带你深度掌握ListView的高级特性,让你的应用界面瞬间专业起来!
ListView提供了5种灵活的显示模式,每种都有其独特的应用场景:
很多开发者不知道如何通过代码高效创建ListView。以下是经过实战验证的最佳实践:
C#namespace AppBasicListView
{
public partial class Form1 : Form
{
private ListView listView;
private ContextMenuStrip contextMenu;
public Form1()
{
InitializeComponent();
InitializeListView();
LoadSampleData();
SetupEvents();
}
private void InitializeListView()
{
listView = new ListView
{
Bounds = new Rectangle(new Point(10, 10), new Size(600, 400)),
View = View.Details, // 使用表格视图
LabelEdit = true, // 允许编辑标签
MultiSelect = false, // 单选模式
GridLines = true, // 显示网格线
Sorting = SortOrder.Ascending,// 自动排序
FullRowSelect = true, // 整行选择
CheckBoxes = false, // 根据需要启用复选框
HeaderStyle = ColumnHeaderStyle.Clickable, // 可点击列头排序
HideSelection = false, // 失去焦点时保持选择状态
ShowItemToolTips = true // 显示工具提示
};
// 添加列
SetupColumns();
// 创建右键菜单
SetupContextMenu();
this.Controls.Add(listView);
}
private void SetupColumns()
{
// 添加列定义
listView.Columns.Add("ID", 60, HorizontalAlignment.Center);
listView.Columns.Add("姓名", 120, HorizontalAlignment.Left);
listView.Columns.Add("部门", 100, HorizontalAlignment.Left);
listView.Columns.Add("职位", 120, HorizontalAlignment.Left);
listView.Columns.Add("入职日期", 100, HorizontalAlignment.Center);
listView.Columns.Add("薪资", 80, HorizontalAlignment.Right);
}
private void SetupContextMenu()
{
contextMenu = new ContextMenuStrip();
var addItem = new ToolStripMenuItem("添加员工", null, AddEmployee_Click);
var editItem = new ToolStripMenuItem("编辑员工", null, EditEmployee_Click);
var deleteItem = new ToolStripMenuItem("删除员工", null, DeleteEmployee_Click);
var refreshItem = new ToolStripMenuItem("刷新", null, RefreshData_Click);
contextMenu.Items.AddRange(new ToolStripItem[] {
addItem, editItem, deleteItem,
new ToolStripSeparator(), refreshItem
});
listView.ContextMenuStrip = contextMenu;
}
private void LoadSampleData()
{
// 示例数据
var employees = new[]
{
new { ID = 1, Name = "张三", Dept = "开发部", Position = "高级工程师", HireDate = "2020-01-15", Salary = 12000 },
new { ID = 2, Name = "李四", Dept = "测试部", Position = "测试工程师", HireDate = "2021-03-20", Salary = 8000 },
new { ID = 3, Name = "王五", Dept = "产品部", Position = "产品经理", HireDate = "2019-08-10", Salary = 15000 },
new { ID = 4, Name = "赵六", Dept = "设计部", Position = "UI设计师", HireDate = "2022-02-01", Salary = 9000 },
new { ID = 5, Name = "钱七", Dept = "开发部", Position = "架构师", HireDate = "2018-05-12", Salary = 18000 }
};
listView.Items.Clear();
foreach (var emp in employees)
{
var item = new ListViewItem(emp.ID.ToString())
{
Tag = emp.ID, // 存储ID用于后续操作
UseItemStyleForSubItems = false
};
item.SubItems.Add(emp.Name);
item.SubItems.Add(emp.Dept);
item.SubItems.Add(emp.Position);
item.SubItems.Add(emp.HireDate);
// 薪资列设置颜色
var salarySubItem = item.SubItems.Add($"¥{emp.Salary:N0}");
if (emp.Salary >= 15000)
{
salarySubItem.ForeColor = Color.Red;
salarySubItem.BackColor = Color.LightYellow;
}
else if (emp.Salary >= 10000)
{
salarySubItem.ForeColor = Color.Blue;
}
listView.Items.Add(item);
}
}
private void SetupEvents()
{
// 双击编辑
listView.DoubleClick += ListView_DoubleClick;
// 键盘事件
listView.KeyDown += ListView_KeyDown;
// 选择改变事件
listView.SelectedIndexChanged += ListView_SelectedIndexChanged;
// 列头点击排序
listView.ColumnClick += ListView_ColumnClick;
// 标签编辑事件
listView.BeforeLabelEdit += ListView_BeforeLabelEdit;
listView.AfterLabelEdit += ListView_AfterLabelEdit;
// 右键菜单打开前检查
contextMenu.Opening += ContextMenu_Opening;
}
#region 事件处理方法
private void ListView_DoubleClick(object sender, EventArgs e)
{
if (listView.SelectedItems.Count > 0)
{
EditEmployee();
}
}
private void ListView_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Delete:
DeleteEmployee();
break;
case Keys.F2:
if (listView.SelectedItems.Count > 0)
listView.SelectedItems[0].BeginEdit();
break;
case Keys.F5:
LoadSampleData();
break;
}
}
private void ListView_SelectedIndexChanged(object sender, EventArgs e)
{
// 可以在这里更新状态栏或其他UI元素
if (listView.SelectedItems.Count > 0)
{
var item = listView.SelectedItems[0];
this.Text = $"选中员工: {item.SubItems[1].Text} - {item.SubItems[2].Text}";
}
else
{
this.Text = "员工管理系统";
}
}
private void ListView_ColumnClick(object sender, ColumnClickEventArgs e)
{
// 简单的列排序实现
listView.ListViewItemSorter = new ListViewColumnSorter(e.Column);
listView.Sort();
}
private void ListView_BeforeLabelEdit(object sender, LabelEditEventArgs e)
{
// 可以在这里控制哪些项目可以编辑
// e.CancelEdit = true; // 取消编辑
}
private void ListView_AfterLabelEdit(object sender, LabelEditEventArgs e)
{
if (string.IsNullOrWhiteSpace(e.Label))
{
e.CancelEdit = true;
MessageBox.Show("员工ID不能为空!", "输入错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
private void ContextMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
{
// 根据选择状态启用/禁用菜单项
bool hasSelection = listView.SelectedItems.Count > 0;
contextMenu.Items[1].Enabled = hasSelection; // 编辑
contextMenu.Items[2].Enabled = hasSelection; // 删除
}
#endregion
#region 右键菜单事件
private void AddEmployee_Click(object sender, EventArgs e)
{
// 添加新员工的逻辑
MessageBox.Show("添加员工功能", "功能演示");
}
private void EditEmployee_Click(object sender, EventArgs e)
{
EditEmployee();
}
private void DeleteEmployee_Click(object sender, EventArgs e)
{
DeleteEmployee();
}
private void RefreshData_Click(object sender, EventArgs e)
{
LoadSampleData();
MessageBox.Show("数据已刷新!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
#endregion
#region 业务方法
private void EditEmployee()
{
if (listView.SelectedItems.Count > 0)
{
var item = listView.SelectedItems[0];
var employeeName = item.SubItems[1].Text;
MessageBox.Show($"编辑员工: {employeeName}", "功能演示");
}
}
private void DeleteEmployee()
{
if (listView.SelectedItems.Count > 0)
{
var item = listView.SelectedItems[0];
var employeeName = item.SubItems[1].Text;
var result = MessageBox.Show($"确定要删除员工 '{employeeName}' 吗?",
"确认删除", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
listView.Items.Remove(item);
MessageBox.Show("员工已删除!", "操作成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
#endregion
}
// 列排序器类
public class ListViewColumnSorter : System.Collections.IComparer
{
private int columnIndex;
private SortOrder sortOrder;
public ListViewColumnSorter(int column)
{
columnIndex = column;
sortOrder = SortOrder.Ascending;
}
public int Compare(object x, object y)
{
ListViewItem itemX = x as ListViewItem;
ListViewItem itemY = y as ListViewItem;
string textX = itemX.SubItems[columnIndex].Text;
string textY = itemY.SubItems[columnIndex].Text;
int result;
// 尝试数字比较
if (decimal.TryParse(textX.Replace("¥", "").Replace(",", ""), out decimal numX) &&
decimal.TryParse(textY.Replace("¥", "").Replace(",", ""), out decimal numY))
{
result = numX.CompareTo(numY);
}
else
{
result = string.Compare(textX, textY);
}
return sortOrder == SortOrder.Ascending ? result : -result;
}
}
}

💎 实战要点:
传统做法往往代码冗长,这里提供一个高效的封装方案:
C#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 AppBasicListView
{
public partial class Form2 : Form
{
private ListView listView;
private Button btnAdd;
private Button btnDelete;
private Button btnEdit;
private TextBox txtSearch;
public Form2()
{
InitializeComponent();
this.Size = new Size(800, 600);
this.Text = "ListView完整示例";
this.StartPosition = FormStartPosition.CenterScreen;
// 创建ListView
listView = new ListView()
{
Dock = DockStyle.Fill,
View = View.Details,
FullRowSelect = true,
GridLines = true,
MultiSelect = false,
AllowColumnReorder = true,
HeaderStyle = ColumnHeaderStyle.Clickable
};
// 创建工具栏
var toolPanel = new Panel()
{
Height = 40,
Dock = DockStyle.Top,
Padding = new Padding(5)
};
btnAdd = new Button()
{
Text = "添加",
Size = new Size(80, 30),
Location = new Point(5, 5)
};
btnEdit = new Button()
{
Text = "编辑",
Size = new Size(80, 30),
Location = new Point(90, 5)
};
btnDelete = new Button()
{
Text = "删除",
Size = new Size(80, 30),
Location = new Point(175, 5)
};
txtSearch = new TextBox()
{
Size = new Size(200, 25),
Location = new Point(280, 7),
PlaceholderText = "输入关键字搜索..."
};
// 添加控件到面板
toolPanel.Controls.AddRange(new Control[] { btnAdd, btnEdit, btnDelete, txtSearch });
// 添加到窗体
this.Controls.Add(listView);
this.Controls.Add(toolPanel);
// 绑定事件
BindEvents();
SetupListView();
AddColumnsAndItems();
}
private void SetupListView()
{
// 启用双缓冲,减少闪烁
typeof(ListView).GetProperty("DoubleBuffered",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance)
?.SetValue(listView, true);
// 设置ListView样式
listView.BackColor = Color.White;
listView.ForeColor = Color.Black;
listView.Font = new Font("Microsoft YaHei", 9F);
// 启用排序功能
listView.ListViewItemSorter = new ListViewItemComparer(0);
}
private void AddColumnsAndItems()
{
// 批量添加列定义
var columns = new[]
{
new { Name = "ID", Width = 80, Align = HorizontalAlignment.Center, Tag = "string" },
new { Name = "Name", Width = 150, Align = HorizontalAlignment.Left, Tag = "string" },
new { Name = "Description", Width = 250, Align = HorizontalAlignment.Left, Tag = "string" },
new { Name = "CreateTime", Width = 150, Align = HorizontalAlignment.Center, Tag = "datetime" },
new { Name = "Status", Width = 100, Align = HorizontalAlignment.Center, Tag = "string" }
};
// 清空现有列
listView.Columns.Clear();
foreach (var col in columns)
{
var column = listView.Columns.Add(col.Name, col.Width, col.Align);
column.Tag = col.Tag; // 用于排序时判断数据类型
}
// 创建示例数据
var items = new[]
{
CreateListViewItem("001", "用户管理", "系统用户管理模块", DateTime.Now.AddDays(-5), "启用"),
CreateListViewItem("002", "权限控制", "角色权限管理功能", DateTime.Now.AddDays(-3), "启用"),
CreateListViewItem("003", "数据备份", "定期数据备份服务", DateTime.Now.AddDays(-1), "禁用"),
CreateListViewItem("004", "日志管理", "系统操作日志记录", DateTime.Now, "启用"),
CreateListViewItem("005", "报表统计", "业务数据统计分析", DateTime.Now.AddDays(-7), "维护中")
};
// 批量添加项目
listView.BeginUpdate(); // 开始批量更新,提高性能
listView.Items.Clear();
listView.Items.AddRange(items);
listView.EndUpdate(); // 结束批量更新
// 自动调整列宽
AutoResizeColumns();
}
private ListViewItem CreateListViewItem(string id, string name, string desc, DateTime createTime, string status)
{
var item = new ListViewItem(id);
item.SubItems.Add(name);
item.SubItems.Add(desc);
item.SubItems.Add(createTime.ToString("yyyy-MM-dd HH:mm"));
item.SubItems.Add(status);
// 根据状态设置颜色
switch (status)
{
case "启用":
item.ForeColor = Color.Green;
break;
case "禁用":
item.ForeColor = Color.Red;
break;
case "维护中":
item.ForeColor = Color.Orange;
break;
}
// 存储完整数据到Tag中,便于后续操作
item.Tag = new ItemData
{
ID = id,
Name = name,
Description = desc,
CreateTime = createTime,
Status = status
};
return item;
}
private void AutoResizeColumns()
{
// 自动调整列宽
foreach (ColumnHeader column in listView.Columns)
{
column.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
column.AutoResize(ColumnHeaderAutoResizeStyle.HeaderSize);
}
}
private void BindEvents()
{
// 按钮事件
btnAdd.Click += BtnAdd_Click;
btnEdit.Click += BtnEdit_Click;
btnDelete.Click += BtnDelete_Click;
// 搜索框事件
txtSearch.TextChanged += TxtSearch_TextChanged;
// ListView事件
listView.ColumnClick += ListView_ColumnClick;
listView.SelectedIndexChanged += ListView_SelectedIndexChanged;
listView.DoubleClick += ListView_DoubleClick;
listView.KeyDown += ListView_KeyDown;
// 右键菜单
SetupContextMenu();
}
private void SetupContextMenu()
{
var contextMenu = new ContextMenuStrip();
contextMenu.Items.Add("编辑", null, (s, e) => EditSelectedItem());
contextMenu.Items.Add("删除", null, (s, e) => DeleteSelectedItem());
contextMenu.Items.Add(new ToolStripSeparator());
contextMenu.Items.Add("刷新", null, (s, e) => RefreshData());
listView.ContextMenuStrip = contextMenu;
}
#region 事件处理
private void BtnAdd_Click(object sender, EventArgs e)
{
// 添加新项目的逻辑
var newId = (listView.Items.Count + 1).ToString("000");
var newItem = CreateListViewItem(newId, "新项目", "新建的项目", DateTime.Now, "启用");
listView.Items.Add(newItem);
newItem.Selected = true;
newItem.EnsureVisible();
}
private void BtnEdit_Click(object sender, EventArgs e)
{
EditSelectedItem();
}
private void BtnDelete_Click(object sender, EventArgs e)
{
DeleteSelectedItem();
}
private void TxtSearch_TextChanged(object sender, EventArgs e)
{
FilterItems(txtSearch.Text);
}
private void ListView_ColumnClick(object sender, ColumnClickEventArgs e)
{
// 列点击排序
var sorter = listView.ListViewItemSorter as ListViewItemComparer;
if (sorter != null)
{
if (sorter.Column == e.Column)
{
sorter.Order = sorter.Order == SortOrder.Ascending ?
SortOrder.Descending : SortOrder.Ascending;
}
else
{
sorter.Column = e.Column;
sorter.Order = SortOrder.Ascending;
}
listView.Sort();
}
}
private void ListView_SelectedIndexChanged(object sender, EventArgs e)
{
// 更新按钮状态
bool hasSelection = listView.SelectedItems.Count > 0;
btnEdit.Enabled = hasSelection;
btnDelete.Enabled = hasSelection;
}
private void ListView_DoubleClick(object sender, EventArgs e)
{
if (listView.SelectedItems.Count > 0)
{
EditSelectedItem();
}
}
private void ListView_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete)
{
DeleteSelectedItem();
}
else if (e.KeyCode == Keys.F5)
{
RefreshData();
}
}
#endregion
#region 辅助方法
private void EditSelectedItem()
{
if (listView.SelectedItems.Count == 0) return;
var selectedItem = listView.SelectedItems[0];
var itemData = selectedItem.Tag as ItemData;
// 这里可以打开编辑对话框
MessageBox.Show($"编辑项目: {itemData?.Name}", "编辑",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void DeleteSelectedItem()
{
if (listView.SelectedItems.Count == 0) return;
var result = MessageBox.Show("确定要删除选中的项目吗?", "确认删除",
MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
foreach (ListViewItem item in listView.SelectedItems)
{
listView.Items.Remove(item);
}
}
}
private void FilterItems(string searchText)
{
if (string.IsNullOrWhiteSpace(searchText))
{
// 显示所有项目
foreach (ListViewItem item in listView.Items)
{
item.Tag = ((ItemData)item.Tag); // 保持原有Tag
}
return;
}
// 简单的文本过滤
listView.BeginUpdate();
foreach (ListViewItem item in listView.Items)
{
bool isMatch = item.SubItems.Cast<ListViewItem.ListViewSubItem>()
.Any(subItem => subItem.Text.Contains(searchText, StringComparison.OrdinalIgnoreCase));
// 这里可以实现隐藏/显示逻辑
// 由于ListView没有直接的隐藏功能,要不就重建Items集合
}
listView.EndUpdate();
}
private void RefreshData()
{
// 刷新数据
AddColumnsAndItems();
}
#endregion
}
// 数据模型
public class ItemData
{
public string ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime CreateTime { get; set; }
public string Status { get; set; }
}
// ListView排序比较器
public class ListViewItemComparer : System.Collections.IComparer
{
public int Column { get; set; }
public SortOrder Order { get; set; } = SortOrder.Ascending;
public ListViewItemComparer(int column)
{
Column = column;
}
public int Compare(object x, object y)
{
var item1 = x as ListViewItem;
var item2 = y as ListViewItem;
if (item1 == null || item2 == null) return 0;
string text1 = item1.SubItems[Column].Text;
string text2 = item2.SubItems[Column].Text;
int result = 0;
// 根据列类型进行不同的比较
var column = item1.ListView.Columns[Column];
if (column.Tag?.ToString() == "datetime")
{
if (DateTime.TryParse(text1, out DateTime date1) &&
DateTime.TryParse(text2, out DateTime date2))
{
result = DateTime.Compare(date1, date2);
}
}
else if (int.TryParse(text1, out int num1) && int.TryParse(text2, out int num2))
{
result = num1.CompareTo(num2);
}
else
{
result = string.Compare(text1, text2, StringComparison.OrdinalIgnoreCase);
}
return Order == SortOrder.Descending ? -result : result;
}
}
}

⚠️ 避坑指南:
用户交互是ListView的核心价值,以下是企业级事件处理方案:
C#private void SetupEventHandlers()
{
// 选择变化事件
listView.ItemSelectionChanged += (sender, e) =>
{
if (e.IsSelected)
{
var selectedItem = e.Item;
// 获取选中项的详细信息
var id = selectedItem.Text;
var name = selectedItem.SubItems[1].Text;
UpdateDetailsPanel(id, name);
}
};
// 双击事件处理
listView.ItemActivate += (sender, e) =>
{
if (listView.SelectedItems.Count > 0)
{
var item = listView.SelectedItems[0];
EditItem(item);
}
};
}
private void UpdateDetailsPanel(string id, string name)
{
// 更新详情面板的逻辑
lblDetails.Text = $"当前选中:{name} (ID: {id})";
}
默认排序往往无法满足业务需求,自定义排序器是进阶必备技能:
C#public class SmartListViewComparer : IComparer
{
private int columnIndex;
private SortOrder sortOrder;
public SmartListViewComparer(int column, SortOrder order = SortOrder.Ascending)
{
columnIndex = column;
sortOrder = order;
}
public int Compare(object x, object y)
{
var itemX = (ListViewItem)x;
var itemY = (ListViewItem)y;
var textX = itemX.SubItems[columnIndex].Text;
var textY = itemY.SubItems[columnIndex].Text;
// 智能比较:数字按数值比较,文本按字母比较
int result = 0;
if (int.TryParse(textX, out int numX) && int.TryParse(textY, out int numY))
{
result = numX.CompareTo(numY);
}
else
{
result = string.Compare(textX, textY, StringComparison.OrdinalIgnoreCase);
}
return sortOrder == SortOrder.Ascending ? result : -result;
}
}
// 应用自定义排序
listView.ListViewItemSorter = new SmartListViewComparer(0);
处理大数据量时,虚拟模式是性能救星:
C#using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AppBasicListView
{
public partial class Form3 : Form
{
private ListView listView;
private Label statusLabel;
private Button loadDataButton;
private Button clearButton;
private TextBox searchTextBox;
private Button searchButton;
private ProgressBar progressBar;
private List<DataModel> virtualData = new List<DataModel>();
private List<DataModel> filteredData = new List<DataModel>();
private bool isFiltered = false;
public Form3()
{
InitializeComponent();
InitializeControls();
}
private void InitializeControls()
{
this.Size = new Size(900, 650);
this.Text = "WinForm 虚拟模式大数据演示";
this.StartPosition = FormStartPosition.CenterScreen;
// 创建控件
CreateControls();
EnableVirtualMode();
}
private void CreateControls()
{
// 顶部控制面板
var topPanel = new Panel
{
Dock = DockStyle.Top,
Height = 80,
Padding = new Padding(10)
};
loadDataButton = new Button
{
Text = "加载大数据集 (10万条)",
Size = new Size(150, 30),
Location = new Point(10, 10)
};
loadDataButton.Click += LoadDataButton_Click;
clearButton = new Button
{
Text = "清空数据",
Size = new Size(80, 30),
Location = new Point(170, 10)
};
clearButton.Click += ClearButton_Click;
// 搜索功能
var searchLabel = new Label
{
Text = "搜索:",
Size = new Size(40, 30),
Location = new Point(270, 15),
TextAlign = ContentAlignment.MiddleLeft
};
searchTextBox = new TextBox
{
Size = new Size(120, 25),
Location = new Point(315, 12)
};
searchTextBox.KeyPress += SearchTextBox_KeyPress;
searchButton = new Button
{
Text = "搜索",
Size = new Size(60, 25),
Location = new Point(445, 12)
};
searchButton.Click += SearchButton_Click;
var resetSearchButton = new Button
{
Text = "重置",
Size = new Size(60, 25),
Location = new Point(515, 12)
};
resetSearchButton.Click += ResetSearchButton_Click;
// 进度条
progressBar = new ProgressBar
{
Size = new Size(200, 20),
Location = new Point(10, 45),
Visible = false
};
// 状态标签
statusLabel = new Label
{
Text = "就绪 - 点击\"加载大数据集\"开始演示",
Size = new Size(400, 20),
Location = new Point(220, 47),
ForeColor = Color.Blue
};
topPanel.Controls.AddRange(new Control[]
{
loadDataButton, clearButton, searchLabel, searchTextBox,
searchButton, resetSearchButton, progressBar, statusLabel
});
// ListView 设置
listView = new ListView
{
Dock = DockStyle.Fill,
View = View.Details,
FullRowSelect = true,
GridLines = true,
VirtualMode = false // 初始状态
};
// 添加列
listView.Columns.Add("ID", 80, HorizontalAlignment.Right);
listView.Columns.Add("名称", 200, HorizontalAlignment.Left);
listView.Columns.Add("描述", 300, HorizontalAlignment.Left);
listView.Columns.Add("创建时间", 150, HorizontalAlignment.Left);
listView.Columns.Add("状态", 100, HorizontalAlignment.Center);
this.Controls.Add(listView);
this.Controls.Add(topPanel);
}
private void EnableVirtualMode()
{
listView.VirtualMode = true;
listView.VirtualListSize = 0;
// 虚拟项检索事件
listView.RetrieveVirtualItem += ListView_RetrieveVirtualItem;
// 搜索虚拟项事件(用于查找功能)
listView.SearchForVirtualItem += ListView_SearchForVirtualItem;
// 缓存虚拟项事件(性能优化)
listView.CacheVirtualItems += ListView_CacheVirtualItems;
}
private void ListView_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
try
{
var dataSource = isFiltered ? filteredData : virtualData;
if (e.ItemIndex >= 0 && e.ItemIndex < dataSource.Count)
{
var data = dataSource[e.ItemIndex];
var item = new ListViewItem(data.Id.ToString());
item.SubItems.Add(data.Name);
item.SubItems.Add(data.Description);
item.SubItems.Add(data.CreatedTime.ToString("yyyy-MM-dd HH:mm:ss"));
item.SubItems.Add(data.Status);
// 根据状态设置颜色
if (data.Status == "活跃")
item.BackColor = Color.LightGreen;
else if (data.Status == "警告")
item.BackColor = Color.LightYellow;
else if (data.Status == "错误")
item.BackColor = Color.LightCoral;
item.Tag = data; // 保存数据引用
e.Item = item;
}
}
catch (Exception ex)
{
// 异常处理
var errorItem = new ListViewItem("ERROR");
errorItem.SubItems.Add(ex.Message);
e.Item = errorItem;
}
}
private void ListView_SearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e)
{
var dataSource = isFiltered ? filteredData : virtualData;
for (int i = e.StartIndex; i < dataSource.Count; i++)
{
if (dataSource[i].Name.StartsWith(e.Text, StringComparison.OrdinalIgnoreCase))
{
e.Index = i;
return;
}
}
e.Index = -1; // 未找到
}
private void ListView_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e)
{
// 这里可以实现数据预缓存逻辑,提高性能
// 例如:预加载 e.StartIndex 到 e.EndIndex 范围的数据
statusLabel.Text = $"缓存项目: {e.StartIndex} - {e.EndIndex}";
}
private async void LoadDataButton_Click(object sender, EventArgs e)
{
loadDataButton.Enabled = false;
progressBar.Visible = true;
progressBar.Value = 0;
var stopwatch = Stopwatch.StartNew();
statusLabel.Text = "正在生成大数据集...";
try
{
// 使用后台任务生成数据
await Task.Run(() => InitializeLargeDataSet());
stopwatch.Stop();
// 更新虚拟列表大小
listView.VirtualListSize = virtualData.Count;
statusLabel.Text = $"✅ 成功加载 {virtualData.Count:N0} 条记录,耗时: {stopwatch.ElapsedMilliseconds} 毫秒";
statusLabel.ForeColor = Color.Green;
}
catch (Exception ex)
{
statusLabel.Text = $"❌ 加载失败: {ex.Message}";
statusLabel.ForeColor = Color.Red;
}
finally
{
loadDataButton.Enabled = true;
progressBar.Visible = false;
}
}
private void InitializeLargeDataSet()
{
virtualData.Clear();
var random = new Random();
var statuses = new[] { "活跃", "非活跃", "警告", "错误" };
var baseTime = DateTime.Now.AddDays(-365);
// 生成10万条测试数据
for (int i = 0; i < 100000; i++)
{
virtualData.Add(new DataModel
{
Id = i + 1,
Name = $"数据项目 {i + 1:D6}",
Description = $"这是第 {i + 1} 个数据项的详细描述信息",
CreatedTime = baseTime.AddMinutes(random.Next(0, 525600)), // 随机时间
Status = statuses[random.Next(statuses.Length)]
});
// 更新进度(每1000条更新一次,避免UI卡顿)
if (i % 1000 == 0)
{
var progress = (int)((double)i / 100000 * 100);
this.Invoke(new Action(() =>
{
progressBar.Value = progress;
statusLabel.Text = $"正在生成数据... {i + 1:N0} / 100,000";
}));
}
}
}
private void ClearButton_Click(object sender, EventArgs e)
{
virtualData.Clear();
filteredData.Clear();
isFiltered = false;
listView.VirtualListSize = 0;
searchTextBox.Clear();
statusLabel.Text = "数据已清空";
statusLabel.ForeColor = Color.Blue;
}
private void SearchButton_Click(object sender, EventArgs e)
{
PerformSearch();
}
private void SearchTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter)
{
PerformSearch();
e.Handled = true;
}
}
private void PerformSearch()
{
var searchText = searchTextBox.Text.Trim();
if (string.IsNullOrEmpty(searchText))
{
ResetSearch();
return;
}
var stopwatch = Stopwatch.StartNew();
statusLabel.Text = "正在搜索...";
// 执行搜索(这里演示简单的名称搜索)
filteredData = virtualData.Where(x =>
x.Name.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0 ||
x.Description.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0)
.ToList();
isFiltered = true;
listView.VirtualListSize = filteredData.Count;
stopwatch.Stop();
statusLabel.Text = $"🔍 找到 {filteredData.Count:N0} 条匹配记录,耗时: {stopwatch.ElapsedMilliseconds} 毫秒";
statusLabel.ForeColor = Color.DarkGreen;
}
private void ResetSearchButton_Click(object sender, EventArgs e)
{
ResetSearch();
}
private void ResetSearch()
{
searchTextBox.Clear();
filteredData.Clear();
isFiltered = false;
listView.VirtualListSize = virtualData.Count;
statusLabel.Text = $"显示全部 {virtualData.Count:N0} 条记录";
statusLabel.ForeColor = Color.Blue;
}
}
// 数据模型
public class DataModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime CreatedTime { get; set; }
public string Status { get; set; }
}
}

🚀 性能提升:虚拟模式可将大数据集的加载时间从秒级降至毫秒级!
通过本文的深度剖析,我们掌握了ListView的三个核心要点:
ListView不仅仅是一个简单的列表控件,它是构建企业级WinForms应用的重要基石。掌握这些进阶技巧,你的C#开发技能将更上一层楼!
💬 互动讨论:
你在ListView开发中遇到过哪些性能瓶颈?在虚拟模式和自定义绘制方面有什么实战经验?欢迎在评论区分享你的见解!
🔖 收藏建议:建议将本文中的代码模板保存到你的代码库中,特别是虚拟模式和自定义排序器的实现,这些都是实际项目中的高频需求。
觉得内容对你有帮助?点赞+转发给更多C#开发同行,让大家一起提升技术水平!
#C#开发 #WinForms #ListView #编程技巧 #性能优化
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!