东拼西凑出来的可编辑、背景色可变的自定义ListView控件

本文介绍了一个自定义的ListView控件实现,该控件支持多种功能,如列表头颜色、列表线颜色的自定义,背景色交替变化等,并提供了详细的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

控件功能:

1、列表头颜色可变

2、列表线颜色可变

3、列表行背景色交替变化

4、行选中色可调

5、单元格双击可编辑(第一列处存在bug)

大致效果


代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace ListViewPro
{
    public partial class ListViewEx : ListView
    {
        private Color _rowBackColor1 = Color.White;
        private Color _rowBackColor2 = Color.FromArgb(255,255,225);
        private Color _selectedColor = Color.FromArgb(49, 106, 196);
        private Color _headColor = Color.FromArgb(236, 233, 216);
        private Color _borderColor = Color.FromArgb(236,233,216);
        private bool _editable = true;
        private TextBox m_tb;

        public ListViewEx() : base()
        {
            base.OwnerDraw = true;
            m_tb = new TextBox();
            m_tb.Multiline = true;
            m_tb.Visible = false;
            this.Controls.Add(m_tb);
        }

        [DefaultValue(typeof(Color), "White")]
        public Color RowBackColor1
        {
            get { return _rowBackColor1; }
            set
            {
                _rowBackColor1 = value;
                base.Invalidate();
            }
        }

        [DefaultValue(typeof(Color), "info")]
        public Color RowBackColor2
        {
            get { return _rowBackColor2; }
            set
            {
                _rowBackColor2 = value;
                base.Invalidate();
            }
        }

        [DefaultValue(typeof(Color), "Highlight")]
        public Color SelectedColor
        {
            get { return _selectedColor; }
            set
            {
                _selectedColor = value;
                base.Invalidate();
            }
        }

        [DefaultValue(typeof(Color), "Control")]
        public Color HeadColor
        {
            get { return _headColor; }
            set
            {
                _headColor = value;
                base.Invalidate();
            }
        }

        [DefaultValue(typeof(Color), "Control")]
        public Color BorderColor
        {
            get { return _borderColor; }
            set
            {
                _borderColor = value;
                base.Invalidate();
            }
        }
        [DefaultValue(typeof(bool), "true")]
        public bool Editable
        {
            get { return _editable; }
            set { _editable = value; }
        }

        protected override void OnDrawColumnHeader(
            DrawListViewColumnHeaderEventArgs e)
        {
            base.OnDrawColumnHeader(e);

            Graphics g = e.Graphics;
            Rectangle bounds = e.Bounds;

            Color baseColor = _headColor;
            Color borderColor = _borderColor;

            RenderBackgroundInternal(
                g,
                bounds,
                baseColor,
                borderColor,
                0.35f,
                true,
                LinearGradientMode.Vertical);

            TextFormatFlags flags = GetFormatFlags(e.Header.TextAlign);
            Rectangle textRect = new Rectangle(
                       bounds.X + 3,
                       bounds.Y,
                       bounds.Width - 6,
                       bounds.Height);

            if (e.Header.ImageList != null)
            {
                Image image = e.Header.ImageIndex == -1 ?
                    null : e.Header.ImageList.Images[e.Header.ImageIndex];
                if (image != null)
                {
                    Rectangle imageRect = new Rectangle(
                        bounds.X + 3,
                        bounds.Y + 2,
                        bounds.Width - 4,
                        bounds.Height - 4);
                    g.InterpolationMode = InterpolationMode.HighQualityBilinear;
                    g.DrawImage(image, imageRect);

                    textRect.X = imageRect.Right + 3;
                    textRect.Width -= imageRect.Width;
                }
            }
            TextRenderer.DrawText(
                   g,
                   e.Header.Text,
                   e.Font,
                   textRect,
                   e.ForeColor,
                   flags);
        }

        protected override void OnDrawItem(DrawListViewItemEventArgs e)
        {
            base.OnDrawItem(e);
            if (View != View.Details)
            {
                e.DrawDefault = true;
            }
        }

        protected override void OnDrawSubItem(DrawListViewSubItemEventArgs e)
        {
            base.OnDrawSubItem(e);
            if (View != View.Details)
            {
                return;
            }
            if (e.ItemIndex == -1)
            {
                return;
            }
            Rectangle bounds = e.Bounds;
            ListViewItemStates itemState = e.ItemState;
            Graphics g = e.Graphics;
            Pen p = new Pen(_borderColor);
            e.Graphics.DrawRectangle(p, bounds);
            if ((itemState & ListViewItemStates.Selected)
                == ListViewItemStates.Selected)
            {
                bounds.Height--;
                Color baseColor = _selectedColor;
                Color borderColor = _selectedColor;
                Color innerBorderColor = _selectedColor;

                RenderBackgroundInternal(
                    g,
                    bounds,
                    baseColor,
                    borderColor,
                    0.35f,
                    true,
                    LinearGradientMode.Vertical);
                bounds.Height++;
            }
            else
            {
                Color backColor = e.ItemIndex % 2 == 0 ?
                _rowBackColor1 : _rowBackColor2;

                using (SolidBrush brush = new SolidBrush(backColor))
                {
                    Rectangle newRect = bounds;
                    newRect.X++;
                    newRect.Width -= 2;
                    newRect.Y++;
                    newRect.Height -= 2;
                    g.FillRectangle(brush, newRect);
                }
            }

            TextFormatFlags flags = GetFormatFlags(e.Header.TextAlign);

            if (e.ColumnIndex == 0)
            {
                if (e.Item.ImageList == null)
                {
                    e.DrawText(flags);
                    return;
                }
                Image image = e.Item.ImageIndex == -1 ?
                    null : e.Item.ImageList.Images[e.Item.ImageIndex];
                if (image == null)
                {
                    e.DrawText(flags);
                    return;
                }
                Rectangle imageRect = new Rectangle(
                    bounds.X + 4,
                    bounds.Y + 2,
                    bounds.Height - 4,
                    bounds.Height - 4);
                g.DrawImage(image, imageRect);

                Rectangle textRect = new Rectangle(
                    imageRect.Right + 3,
                    bounds.Y,
                    bounds.Width - imageRect.Right - 3,
                    bounds.Height);
                TextRenderer.DrawText(
                    g,
                    e.Item.Text,
                    e.Item.Font,
                    textRect,
                    e.Item.ForeColor,
                    flags);
                return;
            }
            e.DrawText(flags);
        }

        protected TextFormatFlags GetFormatFlags(HorizontalAlignment align)
        {
            TextFormatFlags flags =
                    TextFormatFlags.EndEllipsis |
                    TextFormatFlags.VerticalCenter;

            switch (align)
            {
                case HorizontalAlignment.Center:
                    flags |= TextFormatFlags.HorizontalCenter;
                    break;
                case HorizontalAlignment.Right:
                    flags |= TextFormatFlags.Right;
                    break;
                case HorizontalAlignment.Left:
                    flags |= TextFormatFlags.Left;
                    break;
            }

            return flags;
        }

        internal void RenderBackgroundInternal(
          Graphics g,
          Rectangle rect,
          Color baseColor,
          Color borderColor,
          float basePosition,
          bool drawBorder,
          LinearGradientMode mode)
        {
            using(Brush brush = new SolidBrush(baseColor))
            {
                g.FillRectangle(brush, rect);
            }
            if (baseColor.A > 80)
            {
                Rectangle rectTop = rect;
                if (mode == LinearGradientMode.Vertical)
                {
                    rectTop.Height = (int)(rectTop.Height * basePosition);
                }
                else
                {
                    rectTop.Width = (int)(rect.Width * basePosition);
                }
                using (SolidBrush brushAlpha =
                    new SolidBrush(Color.FromArgb(80, 255, 255, 255)))
                {
                    g.FillRectangle(brushAlpha, rectTop);
                }
            }

            if (drawBorder)
            {
                using (Pen pen = new Pen(borderColor))
                {
                    g.DrawRectangle(pen, rect);
                }
            }
        }

        protected override void OnSelectedIndexChanged(EventArgs e)
        {
            this.m_tb.Visible = false;
            base.OnSelectedIndexChanged(e);
        }

        protected override void OnDoubleClick(EventArgs e)
        {
            if(_editable)
            {
                Point tmpPoint = this.PointToClient(Cursor.Position);
                ListViewItem.ListViewSubItem subitem = this.HitTest(tmpPoint).SubItem;
                ListViewItem item = this.HitTest(tmpPoint).Item;
                if (subitem != null)
                {
                    EditItem(subitem);
                }
            }
            base.OnDoubleClick(e);
        }

        private void EditItem(ListViewItem.ListViewSubItem subItem)
        {
            if (this.SelectedItems.Count <= 0)
            {
                return;
            }
            
            Rectangle _rect = subItem.Bounds;
            m_tb.Bounds = _rect;
            m_tb.BringToFront();
            m_tb.Text = subItem.Text;
            m_tb.Leave += new EventHandler(tb_Leave);
            m_tb.TextChanged += new EventHandler(m_tb_TextChanged);
            m_tb.KeyPress += new KeyPressEventHandler(m_tb_KeyPress);
            m_tb.Visible = true;
            m_tb.Tag = subItem;
            m_tb.Select();
        }

        private void tb_Leave(object sender, EventArgs e)
        {
            m_tb.TextChanged -= new EventHandler(m_tb_TextChanged);
            m_tb.KeyPress -= new KeyPressEventHandler(m_tb_KeyPress);
            (sender as TextBox).Visible = false;
        }

        private void m_tb_TextChanged(object sender, EventArgs e)
        {
            if ((sender as TextBox).Tag is ListViewItem.ListViewSubItem)
            {
                (this.m_tb.Tag as ListViewItem.ListViewSubItem).Text = this.m_tb.Text;
            }
        }

        private void m_tb_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
        {
            if (e.KeyChar == '\r')
            {
                m_tb.TextChanged -= new EventHandler(m_tb_TextChanged);
                m_tb.Leave -= new EventHandler(tb_Leave);
                (sender as TextBox).Visible = false;
            }
        }

        protected override void WndProc(ref   Message m)
        {
            if (m.Msg == 0x115 || m.Msg == 0x114)
            {
                this.m_tb.Visible = false;
            }
            base.WndProc(ref m);
        }
    }
}

以上完全参考一下两篇文章所作,

1、http://hi.baidu.com/%B0%D7%D4%C6%D2%BB%C2%C6/blog/item/da42bac3e3c02d5db219a80a.html

2、http://www.cnblogs.com/wanfei/archive/2010/04/23/1718498.html

若有不对之处,请大家多多指正


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值