///可编辑listview类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;
namespace testlistview
{
public class ListViewCell
{
///
/// 单元格所在的行。
///
public ListViewItem Item { get; set; }
///
/// Item 的 Index 值会变成 -1,暂时未找到原因,用这个代替。
///
public int ItemIndex { get; set; }
///
/// 单元格所在的列。
///
public ColumnHeader Column { get; set; }
///
/// 单元格相对于 ListView 的大小和位置。
///
public Rectangle Bounds { get; set; }
}
public class ListViewCellLocator
{
[DllImport("user32")]
public static extern int GetScrollPos(int hwnd, int nBar);
///
/// 根据位置 x、y 获得 ListViewCell。
///
///
/// 工作区坐标表示的 x 轴坐标。
/// 工作区坐标表示的 y 轴坐标。
///
public static ListViewCell GetCell(ListView listView, int x, int y)
{
ListViewCell cell = new ListViewCell();
// 获得单元格所在的行。
cell.Item = listView.GetItemAt(x, y);
if (cell.Item == null)
{
return null;
}
cell.ItemIndex = cell.Item.Index; // 现在 Item.Index 还能用
// 根据各列宽度,获得单元格所在的列,以及 Bounds。
int currentX = cell.Item.GetBounds(ItemBoundsPortion.Entire).Left; // 依次循环各列,表示各列的起点值
int scrollLeft = GetScrollPos(listView.Handle.ToInt32(), 0); // 可能出现了横向滚动条,左边隐藏起来的宽度
for (int i = 0; i < listView.Columns.Count; i++)
{
if (scrollLeft + x >= currentX &&
scrollLeft + x < currentX + listView.Columns[i].Width)
{
cell.Column = listView.Columns[i]; // 列找到了
Rectangle itemBounds = cell.Item.GetBounds(ItemBoundsPortion.Entire);
cell.Bounds = new Rectangle(currentX,
itemBounds.Y,
listView.Columns[i].Width,
itemBounds.Height);
break;
}
currentX += listView.Columns[i].Width;
}
if (cell.Column == null)
{
return null;
}
return cell;
}
}
public class EditableListViewSubmittingEventArgs : EventArgs
{
public ListViewCell Cell { get; set; }
public string Value { get; set; }
}
public delegate void EditableListViewSubmitting(object sender, EditableListViewSubmittingEventArgs e);
class EditableListView
{
public event EditableListViewSubmitting Submitting;
private ListView ListView { get; set; }
private Point MousePosition = new Point();
private TextBox EditBox { get; set; }
public int[] TextBoxColumns { get; set; }
public EditableListView(ListView listView)
{
// 初始化 EditBox
EditBox = new TextBox();
EditBox.Visible = false;
EditBox.KeyUp += new KeyEventHandler(KeyUpHandle);
EditBox.LostFocus += new EventHandler(EditBox_LostForcus);
// 设置 ListView
ListView = listView;
ListView.MouseMove += new MouseEventHandler(delegate(object sender, MouseEventArgs e)
{
// 记录鼠标位置,便于在鼠标动作中使用(有些鼠标动作,比如双击,事件中并不传递鼠标双击时的位置)。
MousePosition.X = e.X;
MousePosition.Y = e.Y;
});
EditBox.Parent = ListView;
// 事件
ListView.DoubleClick += new EventHandler(EditItem);
}
private void KeyUpHandle(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.Escape)
{
LeaveEdit();
}
else if (e.KeyCode == Keys.Enter)
{
SaveEdit();
}
}
private void EditBox_LostForcus(object sender, EventArgs e) {
SaveEdit();
}
private void SaveEdit() {
if (Submitting != null)
{
EditableListViewSubmittingEventArgs args = new EditableListViewSubmittingEventArgs();
if (EditBox.Tag != null)
{
args.Cell = (ListViewCell)EditBox.Tag;
}
else
{
args.Cell = null;
}
args.Value = EditBox.Text;
LeaveEdit();
Submitting(ListView, args);
}
}
private void EditItem(object sender, EventArgs e) {
ListViewCell cell = ListViewCellLocator.GetCell(this.ListView, MousePosition.X, MousePosition.Y);
if (cell == null)
{
return;
}
if (TextBoxColumns.Contains(cell.Column.Index))
{
// 设置 EditBox 的位置、大小、内容、可显示等。
EditBox.Bounds = cell.Bounds;
EditBox.Text = cell.Item.SubItems[cell.Column.Index].Text;
EditBox.Visible = true;
EditBox.Focus();
EditBox.Tag = cell;
}
}
public bool IsEditableColumn(int columnIndex)
{
if (TextBoxColumns.Contains(columnIndex))
{
return true;
}
return false;
}
public void LeaveEdit()
{
EditBox.Visible = false;
EditBox.Tag = null;
}
}
}
///窗体类form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace testlistview
{
public partial class Form1 : Form
{
private EditableListView list;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
listView1.Columns.Add("测试");
listView1.Columns.Add("测试12");
ListViewItem lvi = new ListViewItem();
lvi.Text = "第一列";
lvi.SubItems.Add("第二列");
listView1.Items.Add(lvi);
list = new EditableListView(listView1);
list.TextBoxColumns = new int[] {0, 1, 2, 3 };
list.Submitting += new EditableListViewSubmitting(listViewSaveEditHandler);
}
private void listViewSaveEditHandler(object sender, EditableListViewSubmittingEventArgs e)
{
if (e.Cell == null)
{
return;
}
string value = e.Value;
ListViewItem item = e.Cell.Item;
int itemindex = e.Cell.Column.Index;
item.SubItems[itemindex].Text = value;
}
}
}
plus:如果第二列不能编辑 可以将listview1控件的FullRowSelect属性改为true