完善 C# ListView 系列-可编辑单元格

来源:互联网 发布:在淘宝买摩托车可靠吗 编辑:程序博客网 时间:2024/04/30 05:24

希望是在 ListView 中双击某单元格时,该单元格内容可编辑。

不过 ListView 本身是不带这个功能的,我们要实现的原理是获取双击的是哪个单元格,然后在该单元格显示一个文本框(也可以是其他控件,本文以文本框为例)。

ListViewCell

namespace Yulin.YWinForm{    public class ListViewCell    {        /// <summary>        /// 单元格所在的行。        /// </summary>        public ListViewItem Item { get; set; }        /// <summary>        /// Item 的 Index 值会变成 -1,暂时未找到原因,用这个代替。        /// </summary>        public int ItemIndex { get; set; }        /// <summary>        /// 单元格所在的列。        /// </summary>        public ColumnHeader Column { get; set; }        /// <summary>        /// 单元格相对于 ListView 的大小和位置。        /// </summary>        public Rectangle Bounds { get; set; }    }    public class ListViewCellLocator    {        [DllImport("user32")]        public static extern int GetScrollPos(int hwnd, int nBar);        /// <summary>        /// 根据位置 x、y 获得 ListViewCell。        /// </summary>        /// <param name="listView"></param>        /// <param name="x">工作区坐标表示的 x 轴坐标。</param>        /// <param name="y">工作区坐标表示的 y 轴坐标。</param>        /// <returns></returns>        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;        }    }}
<span style="font-family: SimSun, serif; font-size: 14px;  line-height: 21px; text-indent: 28px;"><strong>EditableListView</strong></span>
<span style="font-family: SimSun, serif; font-size: 14px; line-height: 21px; text-indent: 28px;"></span><pre name="code" class="csharp">namespace Yulin.YWinForm{    public class EditableListViewSubmittingEventArgs : EventArgs    {        public ListViewCell Cell { get; set; }        public string Value { get; set; }    }    public delegate void EditableListViewSubmitting(object sender, EditableListViewSubmittingEventArgs e);    public 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(delegate(object sender, KeyEventArgs e)            {                if (e.KeyCode == Keys.Escape)                {                    LeaveEdit();                }                else if (e.KeyCode == Keys.Enter)                {                    if (Submitting != null)                    {                        EditableListViewSubmittingEventArgs args = new EditableListViewSubmittingEventArgs();                        if (EditBox.Tag != null)                        {                            args.Cell = (ListViewCell)EditBox.Tag;                        }                        else                        {                            args.Cell = null;                        }                        args.Value = EditBox.Text;                        Submitting(listView, args);                    }                }            });            // 设置 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(delegate(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;        }    }}
<span style="font-family: SimSun, serif; font-size: 14px;  line-height: 21px; text-indent: 28px;"><strong>应用</strong></span>
<span style="font-family: SimSun, serif; font-size: 14px;  line-height: 21px; text-indent: 28px;"><strong></strong></span>
<span style="font-family: SimSun, serif; font-size: 14px;  line-height: 21px; text-indent: 28px;"><strong></strong></span>
<span style="font-family: SimSun, serif; font-size: 14px; line-height: 21px; text-indent: 28px;"></span><pre name="code" class="csharp">EditablelistViewSubmittingEventArgs e){    if (e.Cell == null)    {        return;    }    int dataId = Convert.ToInt32(e.Cell.Item.SubItems[_dataIdColumn.Index].Text);    string newValue = e.Value;    // ... 更新代码省略});





0 0
原创粉丝点击