winform中可以折叠的datagridview,自定义控件

winform中可以折叠的datagridview,自定义控件。

目前实现了两层折叠,可以进一步拓展。

public partial class CollDataGridView : DataGridView
    {
        public CollDataGridView()
        {
            InitializeComponent();
        }

        public CollDataGridView(IContainer container)
        {
            container.Add(this);
            InitializeComponent();
            this.RowHeadersVisible = true;
            this.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;
            this.ImageWidth = 15;
            this.ImageHeight = 15;
            this.RowHeadersDefaultCellStyle.Padding = new Padding(this.RowHeadersWidth);
            this.CurrentCellDirtyStateChanged += CollDataGridView_CurrentCellDirtyStateChanged;
        }

        private void CollDataGridView_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            if (this.IsCurrentCellDirty)
            {
                this.CommitEdit(DataGridViewDataErrorContexts.Commit);
            }
        }

        #region property
        /// <summary>
        /// 行首图片宽度
        /// </summary>
        [
        Category("CollDataGridViewProperties"),
        Description("行首图片宽度"),
        Bindable(true)
        ]
        public int ImageWidth { get; set; }

        /// <summary>
        /// 行首图片高度
        /// </summary>
        [
        Category("CollDataGridViewProperties"),
        Description("行首图片高度"),
        Bindable(true)
        ]
        public int ImageHeight { get; set; }

        /// <summary>
        /// 行首收缩图标
        /// </summary>
        [
        Category("CollDataGridViewProperties"),
        Description("行首收缩图标"),
        Bindable(true)
        ]
        public Image ImgExpand { get; set; }

        /// <summary>
        /// 行首展开图片
        /// </summary>
        [
        Category("CollDataGridViewProperties"),
        Description("行首展开图片"),
        Bindable(true)
        ]
        public Image ImgCollapse { get; set; }
        #endregion

        protected override void OnRowPostPaint(DataGridViewRowPostPaintEventArgs e)
        {
            base.OnRowPostPaint(e);

            DataGridViewRow row = this.Rows[e.RowIndex];
            Rectangle rectBack = new Rectangle(e.RowBounds.Location.X, e.RowBounds.Location.Y, this.RowHeadersWidth, e.RowBounds.Height - 1);

            Rectangle rectLineBottom = new Rectangle(e.RowBounds.Location.X, e.RowBounds.Location.Y + e.RowBounds.Height - 1, this.RowHeadersWidth, 1);

            if (row is CollDataGridViewRow && (row as CollDataGridViewRow).Rows.Count != 0)
            {
                Rectangle rect = new Rectangle(e.RowBounds.Location.X + 4, e.RowBounds.Location.Y + 4, this.ImageWidth, this.ImageHeight);
                Image img = null;
                if ((row as CollDataGridViewRow).IsCollapse)
                {
                    img = this.ImgExpand;
                }
                else
                {
                    img = this.ImgCollapse;
                }
                e.Graphics.DrawImage(img, rect);
            }
        }

        /// <summary>
        /// 增加点击行首折叠功能
        /// </summary>
        /// <param name="e"></param>
        protected override void OnRowHeaderMouseClick(DataGridViewCellMouseEventArgs e)
        {
            DataGridViewRow row = this.Rows[e.RowIndex];
            if (row is CollDataGridViewRow)
            {
                if ((row as CollDataGridViewRow).IsCollapse == true)
                {
                    this.Expand(e.RowIndex);
                }
                else
                {
                    this.Collapse(e.RowIndex);
                }
            }
            base.OnRowHeaderMouseClick(e);
        }

        public void Expand(int nRowIndex)
        {
            DataGridViewRow row = this.Rows[nRowIndex];
            if (row is CollDataGridViewRow)
            {
                if ((row as CollDataGridViewRow).IsCollapse == true)
                {
                    (row as CollDataGridViewRow).IsCollapse = false;

                    if ((row as CollDataGridViewRow).Rows.Count != 0)
                    {
                        for (int i = 0; i < (row as CollDataGridViewRow).Rows.Count; i++)
                        {
                            this.Rows.Insert(nRowIndex + 1 + i, (row as CollDataGridViewRow).Rows[i]);
                            //展开子条目时重绘子条目背景色,防止与主条目背景色不一致
                            (row as CollDataGridViewRow).Rows[i].DefaultCellStyle.BackColor =
                                (row as CollDataGridViewRow).DefaultCellStyle.BackColor;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 折叠
        /// </summary>
        /// <param name="nRowIndex">行号</param>
        public void Collapse(int nRowIndex)
        {
            DataGridViewRow row = this.Rows[nRowIndex];
            if ((row as CollDataGridViewRow).IsCollapse == false)
            {
                if ((row as CollDataGridViewRow).Rows.Count != 0)
                {
                    this.RemoveAllSubRow((CollDataGridViewRow)row, false);
                }
                (row as CollDataGridViewRow).IsCollapse = true;
            }
        }

        /// <summary>
        /// 删除集合除首条外的所有子条目
        /// </summary>
        /// <param name="row">折叠行对象</param>
        /// <param name="flag"></param>
        private void RemoveAllSubRow(CollDataGridViewRow row, bool flag)
        {
            if (row.Rows.Count != 0)
            {
                if (!row.IsCollapse)
                {
                    for (int i = 0; i < row.Rows.Count; i++)
                    {
                        if (row.Rows[i] is CollDataGridViewRow)
                        {
                            RemoveAllSubRow((CollDataGridViewRow)row.Rows[i], true);
                        }
                        else
                        {
                            this.Rows.Remove(row.Rows[i]);
                        }
                    }
                }
                if (flag)
                {
                    row.IsCollapse = true;
                    this.Rows.Remove(row);
                }
            }
        }

        public void AddColumns(JObject obj)
        {
            int cloumIndex = 0;
            foreach (var item in obj)
            {
                var name = item.Key;
                AddTextBoxColumn(cloumIndex, name, name);
                cloumIndex++;
            }
        }

        public void AddData(JArray array, int ignoreIndex, int childNum)
        {
            foreach (var item in array)
            {
                var childList = new List<JObject>();
                for (int i = 0; i < childNum; i++)
                {
                    childList.Add((JObject)item);
                }

                CollDataGridViewRow collapseRow = new CollDataGridViewRow();
                collapseRow.IsCollapse = true;
                collapseRow.GroupTag = childList;

                DataGridViewCheckBoxCell cell = new DataGridViewCheckBoxCell();
                cell.Value = false;
                collapseRow.Cells.Add(cell);//不预先添加则无法折叠--相当于插入了空行

                for (int i = 1; i < childNum + 1; i++)
                {
                    DataGridViewRow row = new DataGridViewRow();
                    cell = new DataGridViewCheckBoxCell();
                    cell.Value = false;
                    row.Cells.Add(cell);//不预先添加则无法折叠
                    row.Tag = i;
                    collapseRow.Rows.Add(row);
                }

                var rownum = this.Rows.Add(collapseRow);
                this.Expand(rownum);

                //Add Data
                for (int i = rownum; i < rownum + childNum + 1; i++)
                {
                    if (i == rownum)
                    {
                        for (int k = 0; k < ignoreIndex; k++)
                        {
                            DataGridViewTextBoxCell cellTextBox = new DataGridViewTextBoxCell();
                            cellTextBox.Value = "";
                            this.Rows[i].Cells[k] = cellTextBox;
                        }
                    }
                    int j = ignoreIndex;
                    foreach (JProperty item2 in item)
                    {
                        this.Rows[i].Cells[j].Value = item2.Value;
                        j++;
                    }
                }
            }
        }

        private void AddTextBoxColumn(int index, string name, string headerText)
        {
            DataGridViewTextBoxColumn column = new DataGridViewTextBoxColumn();
            column.AutoSizeMode = DataGridViewAutoSizeColumnMode.NotSet;
            column.SortMode = DataGridViewColumnSortMode.NotSortable;
            column.Name = name;
            column.HeaderText = headerText;
            this.Columns.Insert(index, column);
        }
    }

    public class CollDataGridViewRow : DataGridViewRow
    {
        #region Private fields

        private CollDataGridViewRowCollection m_rowCollection = new CollDataGridViewRowCollection();

        #endregion

        #region Public Properties

        /// <summary>
        /// 是否展开
        /// </summary>
        public bool IsCollapse
        {
            get;
            set;
        }

        /// <summary>
        /// 折叠控件的集合
        /// </summary>
        public CollDataGridViewRowCollection Rows
        {
            get { return m_rowCollection; }
            set { m_rowCollection = value; }
        }

        /// <summary>
        /// 集合行的Tag,用于存储集合所有的信息
        /// </summary>
        public object GroupTag
        {
            get;
            set;
        }

        #endregion
    }

    public class CollDataGridViewRowCollection : IEnumerable<DataGridViewRow>, ICollection<DataGridViewRow>
    {
        private List<DataGridViewRow> m_list = new List<DataGridViewRow>();

        public DataGridViewRow this[int index]
        {
            get
            {
                if (index >= m_list.Count)
                {
                    throw new ArgumentOutOfRangeException("index");
                }
                return m_list[index];
            }
        }

        #region IEnumerable<DataGridViewRow> Member

        public IEnumerator<DataGridViewRow> GetEnumerator()
        {
            if (m_list.Count == 0)
            {
                throw new ArgumentOutOfRangeException("collection is null");
            }
            for (int i = 0; i < m_list.Count; i++)
            {
                yield return m_list[i];
            }
        }

        #endregion

        #region IEnumerable Member

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            if (m_list.Count == 0)
            {
                throw new ArgumentOutOfRangeException("collection is null");
            }
            for (int i = 0; i < m_list.Count; i++)
            {
                yield return m_list[i];
            }
        }

        #endregion

        #region ICollection<DataGridViewRow> Member

        public void Add(DataGridViewRow item)
        {
            m_list.Add(item);
        }

        public void Clear()
        {
            m_list.Clear();
        }

        public bool Contains(DataGridViewRow item)
        {
            return m_list.Contains(item);
        }

        public void CopyTo(DataGridViewRow[] array, int arrayIndex)
        {
            m_list.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get { return m_list.Count; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        public bool Remove(DataGridViewRow item)
        {
            return m_list.Remove(item);
        }

        #endregion
    }

具体的实现如下:

1.定义折叠图片

dgv.ImgCollapse = new FontAwesome.Properties(FontAwesome.Type.MinusSquareO) { ForeColor = Color.Black, BorderColor = Color.Transparent, BackColor = Color.Transparent }.AsImage();

            dgv.ImgExpand = new FontAwesome.Properties(FontAwesome.Type.PlusSquareO) { ForeColor = Color.Black, BorderColor = Color.Transparent, BackColor = Color.Transparent }.AsImage();
            dgv.ImageHeight = 15;
            dgv.ImageWidth = 15;

2.添加列和数据

 dgv.AddColumns((JObject)obj[name].First);
 dgv.AddData((JArray)obj[name], 2, 3);

 

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值