加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

c#可编辑的listview控件

(2013-06-13 16:08:22)
标签:

it

///可编辑listview类EditableListView.cs
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

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有