zoukankan      html  css  js  c++  java
  • 自绘 TreeDataView 控件

    自定义TreeDataView 控件,百万级别数据秒绘。

    最近需要使用到数据展现,需要对数据折叠展现。网上找了许多控件,如:TreeListView,TreevDataGirdView等,但是都无法到达效果,而且加载百万条数据时,绘制灰常的卡顿。

    话不多说。先上效果图

    1 准备工作,创建两个类,用户绘制行与列

      public class UserRow
        {
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="level">节点等级</param>
            public UserRow(int level)
            {
                _level = level;
                strFmt.Alignment = StringAlignment.Near; //文本水平居中
                strFmt.LineAlignment = StringAlignment.Center; //文本垂直居中
            }
    
            int _level = 0;
    
            public int Level
            {
                get { return _level; }
            }
    
            public UserRow Parent { get; set; } = null;
    
            public float PointX = 0;
    
            public float PointY = 0;
    
    
            //public float RowHeigth = 20;
    
            public bool ExpandEvent = false;
    
            private bool _expand = false;
    
            public bool Expand
            {
                get { return _expand; }
                set { _expand = value; }
            }
    
            private float _marginLeft = 30;
            public float MarginLeft
            {
                get
                {
                    return _marginLeft;
                }
            }
    
            public bool IsSelected = false;
    
            public List<UserCell> Cells = new List<UserCell>();
    
            List<UserRow> _subrows = new List<UserRow>();
            public List<UserRow> SubRows
            {
                get { return _subrows; }
            }
    
    
            StringFormat strFmt = new System.Drawing.StringFormat();
            Font myFont = new Font("宋体", 10);
            public float Draw(Graphics g, float dx, float dy, float MapLocationX, float MapLocationY, float h, float w, List<UserCell> colums)
            {
                PointY = dy;
                float margleft = calcMarginLeft(this);
                float x = PointX - MapLocationX ;
                float y = PointY - MapLocationY;
    
                if (_level == 0)
                {
                    g.FillRectangle(Brushes.LightSkyBlue, x, y + 1, w - 2, h - 1);
                }
                else
                {
                    g.FillRectangle(Brushes.White, x, y + 1, w - 2, h - 1);
                }
                if (this.SubRows.Count > 0)
                {
                    RectangleF plusRect = new RectangleF(x + margleft - 15, y + 5, 10, 10);// +-号的大小 是9 * 9
                    g.FillRectangle(Brushes.White, plusRect);
                    g.DrawRectangle(new Pen(Brushes.Black), plusRect.X, plusRect.Y, plusRect.Width, plusRect.Height);
                    if (this.Expand)
                    {
                        g.DrawString("-", new Font("宋体", 9), Brushes.Black, plusRect);
                    }
                    else
                    {
                        g.DrawString("+", new Font("宋体", 9), Brushes.Black, plusRect);
                    }
                }
    
                float startPointX = x + margleft ;
                for (int i = 0; i < colums.Count; i++)
                {
                    if (colums[i].IsViszble && i< Cells.Count)
                    {
                        RectangleF rf = new RectangleF(startPointX, y + 1, colums[i].Width, h - 1);
                        if (colums[i].IsSelect)
                        {
                            g.FillRectangle(Brushes.Black, rf);
                            g.DrawString(Cells[i].Value, myFont, Brushes.White, rf, strFmt);
                        }
                        else
                        {
                            g.FillRectangle(Brushes.Transparent, rf);
                            g.DrawString(Cells[i].Value, myFont, Brushes.Black, rf, strFmt);
                        }
                        //g.DrawLine(new Pen(Brushes.White, 1), startPointX, y, startPointX, y + h);
    
                        startPointX += colums[i].Width;
                    }
    
                }
    
                Pen mypen;
                if (IsSelected)
                {
                    mypen = new Pen(Brushes.Red, 1);
                    g.DrawRectangle(mypen, x, y + 1, w -2, h - 1);
                }
                else
                {
                    mypen = new Pen(Brushes.White, 1);
                    g.DrawRectangle(mypen, x, y + 1,w -2, h - 1);
                }
    
                
    
    
                return startPointX + margleft;
            }
    
            public float CalcMaxWidth()
            {
                float width = PointX;
                float margleft = calcMarginLeft(this);
                for (int i = 0; i < Cells.Count; i++)
                {
                    width += Cells[i].Width;
                }
                return width + margleft;
            }
            public float calcMarginLeft(UserRow row)
            {
                return (row.Level + 1) * row.MarginLeft;
                //if (row.Parent != null)
                //{
                //    float t = calcMarginLeft(row.Parent);
                //    return row.Parent.MarginLeft + t;
                //}
                //else
                //{
                //    return row.MarginLeft;
                //}
            }
    
            public bool IsSelect(float dx, float dy, float h, float w)
            {
                float margleft = calcMarginLeft(this);
                
                ExpandEvent = false;
                if (dx <= PointX + w && dx >= PointX && dy <= PointY + h && dy >= PointY)
                {
                    IsSelected = true;
                    RectangleF plusRect = new RectangleF(PointX + margleft - 15, PointY + 5, 10, 10);// +-号的大小 是9 * 9
                    if (dx <= plusRect.X + plusRect.Width && dx >= plusRect.X && dy <= plusRect.Y + plusRect.Height && dy >= plusRect.Y)
                    {
                        _expand = !_expand;
                        ExpandEvent = true;
    
                    }
                }
                else
                {
                    IsSelected = false;
                }
                
                return IsSelected;
    
    
            }
    
        }
    
        public class UserCell
        {
            /// <summary>
            /// 当前值
            /// </summary>
            public string Value { get; set; }
            /// <summary>
            /// 默认单元格宽度
            /// </summary>
            public float Width { get; set; } = 80;
            /// <summary>
            /// 是否显示
            /// </summary>
            public bool IsViszble { get; set; } = true;
            /// <summary>
            /// 是否选中单元格
            /// </summary>
            public bool IsSelect { get; set; } = false;
    
    
        }

    2 添加用户控件,然后在控件上面添加 三个控件,PictureBox,vScrollBar1,hScrollBar1

    PictureBox 用于绘制数据,vScrollBar1,hScrollBar1用于移动数据

    设计代码

    namespace UserTreeTable
    {
        partial class UserControl1
        {
            /// <summary> 
            /// 必需的设计器变量。
            /// </summary>
            private System.ComponentModel.IContainer components = null;
    
            /// <summary> 
            /// 清理所有正在使用的资源。
            /// </summary>
            /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    
            #region 组件设计器生成的代码
    
            /// <summary> 
            /// 设计器支持所需的方法 - 不要修改
            /// 使用代码编辑器修改此方法的内容。
            /// </summary>
            private void InitializeComponent()
            {
                this.components = new System.ComponentModel.Container();
                this.vScrollBar1 = new System.Windows.Forms.VScrollBar();
                this.hScrollBar1 = new System.Windows.Forms.HScrollBar();
                this.pbImg = new System.Windows.Forms.PictureBox();
                this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
                this.折叠ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
                this.折叠层一ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
                this.折叠层二ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
                this.展开ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
                this.展开层一ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
                this.展开层二ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
                ((System.ComponentModel.ISupportInitialize)(this.pbImg)).BeginInit();
                this.contextMenuStrip1.SuspendLayout();
                this.SuspendLayout();
                // 
                // vScrollBar1
                // 
                this.vScrollBar1.Dock = System.Windows.Forms.DockStyle.Right;
                this.vScrollBar1.Location = new System.Drawing.Point(439, 0);
                this.vScrollBar1.Name = "vScrollBar1";
                this.vScrollBar1.Size = new System.Drawing.Size(17, 325);
                this.vScrollBar1.TabIndex = 0;
                this.vScrollBar1.Scroll += new System.Windows.Forms.ScrollEventHandler(this.vScrollBar1_Scroll);
                this.vScrollBar1.ValueChanged += new System.EventHandler(this.vScrollBar1_ValueChanged);
                // 
                // hScrollBar1
                // 
                this.hScrollBar1.Dock = System.Windows.Forms.DockStyle.Bottom;
                this.hScrollBar1.Location = new System.Drawing.Point(0, 308);
                this.hScrollBar1.Name = "hScrollBar1";
                this.hScrollBar1.Size = new System.Drawing.Size(439, 17);
                this.hScrollBar1.TabIndex = 1;
                this.hScrollBar1.Scroll += new System.Windows.Forms.ScrollEventHandler(this.hScrollBar1_Scroll);
                this.hScrollBar1.ValueChanged += new System.EventHandler(this.hScrollBar1_ValueChanged);
                // 
                // pbImg
                // 
                this.pbImg.BackColor = System.Drawing.SystemColors.Control;
                this.pbImg.ContextMenuStrip = this.contextMenuStrip1;
                this.pbImg.Dock = System.Windows.Forms.DockStyle.Fill;
                this.pbImg.Location = new System.Drawing.Point(0, 0);
                this.pbImg.Name = "pbImg";
                this.pbImg.Size = new System.Drawing.Size(439, 308);
                this.pbImg.TabIndex = 2;
                this.pbImg.TabStop = false;
                this.pbImg.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
                this.pbImg.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseDown);
                this.pbImg.Resize += new System.EventHandler(this.pbImg_Resize);
                // 
                // contextMenuStrip1
                // 
                this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
                this.折叠ToolStripMenuItem,
                this.展开ToolStripMenuItem});
                this.contextMenuStrip1.Name = "contextMenuStrip1";
                this.contextMenuStrip1.Size = new System.Drawing.Size(153, 70);
                // 
                // 折叠ToolStripMenuItem
                // 
                this.折叠ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
                this.折叠层一ToolStripMenuItem,
                this.折叠层二ToolStripMenuItem});
                this.折叠ToolStripMenuItem.Name = "折叠ToolStripMenuItem";
                this.折叠ToolStripMenuItem.Size = new System.Drawing.Size(100, 22);
                this.折叠ToolStripMenuItem.Text = "折叠";
                // 
                // 折叠层一ToolStripMenuItem
                // 
                this.折叠层一ToolStripMenuItem.Name = "折叠层一ToolStripMenuItem";
                this.折叠层一ToolStripMenuItem.Size = new System.Drawing.Size(124, 22);
                this.折叠层一ToolStripMenuItem.Text = "折叠层一";
                this.折叠层一ToolStripMenuItem.Click += new System.EventHandler(this.折叠层一ToolStripMenuItem_Click);
                // 
                // 折叠层二ToolStripMenuItem
                // 
                this.折叠层二ToolStripMenuItem.Name = "折叠层二ToolStripMenuItem";
                this.折叠层二ToolStripMenuItem.Size = new System.Drawing.Size(124, 22);
                this.折叠层二ToolStripMenuItem.Text = "折叠层二";
                this.折叠层二ToolStripMenuItem.Click += new System.EventHandler(this.折叠层二ToolStripMenuItem_Click);
                // 
                // 展开ToolStripMenuItem
                // 
                this.展开ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
                this.展开层一ToolStripMenuItem,
                this.展开层二ToolStripMenuItem});
                this.展开ToolStripMenuItem.Name = "展开ToolStripMenuItem";
                this.展开ToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
                this.展开ToolStripMenuItem.Text = "展开";
                // 
                // 展开层一ToolStripMenuItem
                // 
                this.展开层一ToolStripMenuItem.Name = "展开层一ToolStripMenuItem";
                this.展开层一ToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
                this.展开层一ToolStripMenuItem.Text = "展开层一";
                this.展开层一ToolStripMenuItem.Click += new System.EventHandler(this.展开层一ToolStripMenuItem_Click);
                // 
                // 展开层二ToolStripMenuItem
                // 
                this.展开层二ToolStripMenuItem.Name = "展开层二ToolStripMenuItem";
                this.展开层二ToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
                this.展开层二ToolStripMenuItem.Text = "展开层二";
                this.展开层二ToolStripMenuItem.Click += new System.EventHandler(this.展开层二ToolStripMenuItem_Click);
                // 
                // UserControl1
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.Controls.Add(this.pbImg);
                this.Controls.Add(this.hScrollBar1);
                this.Controls.Add(this.vScrollBar1);
                this.Name = "UserControl1";
                this.Size = new System.Drawing.Size(456, 325);
                this.Resize += new System.EventHandler(this.UserControl1_Resize);
                ((System.ComponentModel.ISupportInitialize)(this.pbImg)).EndInit();
                this.contextMenuStrip1.ResumeLayout(false);
                this.ResumeLayout(false);
    
            }
    
            #endregion
    
            private System.Windows.Forms.VScrollBar vScrollBar1;
            private System.Windows.Forms.HScrollBar hScrollBar1;
            private System.Windows.Forms.PictureBox pbImg;
            private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
            private System.Windows.Forms.ToolStripMenuItem 折叠ToolStripMenuItem;
            private System.Windows.Forms.ToolStripMenuItem 折叠层一ToolStripMenuItem;
            private System.Windows.Forms.ToolStripMenuItem 折叠层二ToolStripMenuItem;
            private System.Windows.Forms.ToolStripMenuItem 展开ToolStripMenuItem;
            private System.Windows.Forms.ToolStripMenuItem 展开层一ToolStripMenuItem;
            private System.Windows.Forms.ToolStripMenuItem 展开层二ToolStripMenuItem;
        }
    }

    3  在自定义控件UserControl1中实现绘制

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace UserTreeTable
    {
        public partial class UserControl1 : UserControl
        {
            public UserControl1(List<UserRow> rows)
            {
                InitializeComponent();
    
                this.Load += UserControl1_Load;
                this.pbImg.MouseWheel += PbImg_MouseWheel;
                Rows = rows;
            }
    
           /// <summary>
           /// 所有行
           /// </summary>
            public List<UserRow> Rows = new List<UserRow>();
    
            /// <summary>
            /// 所有列
            /// </summary>
            public SortedList<int, UserRow> HeadColumns = new SortedList<int, UserRow>();
    
            /// <summary>
            /// 选中的列
            /// </summary>
            List<UserCell> selectHeadColumns = new List<UserCell>();
    
    
            /// <summary>
            /// 选中行
            /// </summary>
            UserRow _selectRow;
    
            /// <summary>
            /// 图像平移后横坐标偏移的像素
            /// </summary>
            public float MapLocationX = 0;
            /// <summary>
            ///  图像平移后纵坐标偏移的像素
            /// </summary>
            public float MapLocationY = 0;
    
            /// <summary>
            /// 固定行号
            /// </summary>
            const int rowHeight = 20;
            /// <summary>
            /// 默认行宽
            /// </summary>
            float rowWidth = 100;
    
            //float MaxHeight = 0;
            //float MaxWidth = 0;
    
            private void UserControl1_Load(object sender, EventArgs e)
            {
                CalcMapSize();
                if (Rows.Count > 0)
                    _selectRow = Rows[0];
            }
    
            private void PbImg_MouseWheel(object sender, MouseEventArgs e)
            {
                if (e.Delta > 0)
                {
                    if (vScrollBar1.Value - rowHeight > 0)
                    {
                        vScrollBar1.Value -= rowHeight;
                    }
                    else
                    {
                        vScrollBar1.Value = vScrollBar1.Minimum;
                    }
    
                }
                else
                {
                    if (vScrollBar1.Value + rowHeight < vScrollBar1.Maximum)
                    {
                        vScrollBar1.Value += rowHeight;
                    }
                    else
                    {
                        vScrollBar1.Value = vScrollBar1.Maximum;
                    }
                }
                if (MapLocationY != vScrollBar1.Value)
                {
                    MapLocationY = vScrollBar1.Value;
                    pbImg.Refresh();
                }
    
            }
    
    
    
            public void CalcMapSize()
            {
                float w = 0, h = 0;
                foreach (UserRow c1 in HeadColumns.Values)
                {
                    float w1 = c1.CalcMaxWidth();
                    if (w < w1)
                    {
                        w = w1;
                    }
                    
                }
                rowWidth = w;
                if (rowWidth > pbImg.Width)
                {
                    hScrollBar1.Enabled = true;
                    hScrollBar1.Minimum = 0;
                    hScrollBar1.Maximum = (int)rowWidth - pbImg.Width +10;
                    hScrollBar1.LargeChange = 10;
                    hScrollBar1.SmallChange = 10;
                }
                else
                {
                    rowWidth = pbImg.Width;
                    MapLocationX = 0;
                    hScrollBar1.Enabled = false;
                    //hScrollBar1.Visible = false;
                }
    
                foreach (UserRow u1 in Rows)
                {
                    h += rowHeight;              
                    if(u1.Expand)
                    {
                        foreach (UserRow u2 in u1.SubRows)
                        {
                            h += rowHeight;
                           
                            if (u2.Expand)
                            {
                                foreach (UserRow u3 in u2.SubRows)
                                {
                                    h += rowHeight;
                                    
                                }
                            }
                        }
                    }
                }
                
    
                int vscrollmaxNum = (int)h - pbImg.Height + 20;
                if (vscrollmaxNum != vScrollBar1.Maximum)
                {
                    if (h > pbImg.Height)
                    {
                        vScrollBar1.Enabled = true;
                        vScrollBar1.Minimum = 0;
                        vScrollBar1.Maximum = vscrollmaxNum;
                        vScrollBar1.LargeChange = rowHeight;
                        vScrollBar1.SmallChange = rowHeight;
                        
                    }
                    else
                    {
                        MapLocationY = 0;
                        vScrollBar1.Enabled = false;
                    }
    
                }
                
               
                
            }
    
    
            void Drawing(Graphics g)
            {
                float pointX = 0;
                float pointY = rowHeight;
                float scrollY = this.vScrollBar1.Value;
                //float tempHeight = scrollY + this.panel2.ClientSize.Height;
                float tempHeight = this.vScrollBar1.Value + pbImg.Height;
                
                foreach (UserRow u1 in Rows)
                {
                    if (pointY <= tempHeight && pointY >= scrollY)
                    {
                        u1.Draw(g, pointX, pointY, MapLocationX, MapLocationY, rowHeight, rowWidth, HeadColumns[u1.Level].Cells);
                    }
    
                    pointY += rowHeight;
    
                    if (u1.Expand == true)
                    {
                        foreach (UserRow u2 in u1.SubRows)
                        {
                            if (pointY <= tempHeight && pointY >= scrollY)
                            {
                                u2.Draw(g, pointX, pointY, MapLocationX, MapLocationY, rowHeight, rowWidth, HeadColumns[u2.Level].Cells);
                            }
    
                            pointY += rowHeight;
                            if (u2.Expand)
                            {
                                foreach (UserRow u3 in u2.SubRows)
                                {
                                    if (pointY <= tempHeight && pointY >= scrollY)
                                    {
                                        u3.Draw(g, pointX, pointY, MapLocationX, MapLocationY, rowHeight, rowWidth, HeadColumns[u3.Level].Cells);
                                    }
    
                                    pointY += rowHeight;
                                }
                            }
                        }
                    }
                }
    
            }
    
            void DrawHead(Graphics g)
            {
                StringFormat strFmt = new System.Drawing.StringFormat();
                strFmt.Alignment = StringAlignment.Near; //文本水平居中
                strFmt.LineAlignment = StringAlignment.Center; //文本垂直居中
    
                Rectangle rect = new Rectangle(0, 0, (int)rowWidth + 10, rowHeight);
                Brush b = new System.Drawing.Drawing2D.LinearGradientBrush(rect, Color.Gray, Color.LightGray, System.Drawing.Drawing2D.LinearGradientMode.Vertical);
                g.FillRectangle(b, rect);
    
                if (_selectRow != null)
                {
                    float margleft = _selectRow.calcMarginLeft(_selectRow);
                    float startPointX = margleft - MapLocationX;
                    UserRow headrow = HeadColumns[_selectRow.Level];
                    foreach (UserCell c in headrow.Cells)
                    {
                        RectangleF rf = new RectangleF(startPointX, 2, c.Width, rowHeight - 1);
                        if (c.IsSelect)
                        {
                            g.FillRectangle(Brushes.Black, rf);
                            g.DrawString(c.Value, this.Font, Brushes.White, rf, strFmt);
                        }
                        else
                        {
                            g.FillRectangle(Brushes.Transparent, rf);
                            g.DrawString(c.Value, this.Font, Brushes.Black, rf, strFmt);
                        }
                        g.DrawLine(new Pen(Brushes.White, 1), startPointX, 0, startPointX, rowHeight);
    
                        startPointX += c.Width;
                    }
                    g.DrawLine(new Pen(Brushes.White, 1), startPointX, 0, startPointX, rowHeight);
                }
    
            }
    
            private void pictureBox1_Paint(object sender, PaintEventArgs e)
            {
                Graphics g = e.Graphics;
                Drawing(g);
                DrawHead(g);
            }
    
            private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
            {
                if (e.Button == MouseButtons.Left)
                {
                    float y = e.Y;
                    if (e.Y < rowHeight)
                    {
                        UserCell headcell = SelectHeadIndex(e.X, e.Y);
                        if (headcell != null)
                        {
                            this.pbImg.Refresh();
                        }
                    }
                    else
                    {
                        UserRow tempselectRow = SelectRow(e.X + MapLocationX, e.Y + MapLocationY);
                        if (tempselectRow != null)
                        {
                            if (tempselectRow != _selectRow)
                            {
                                if (_selectRow != null)
                                {
                                    _selectRow.IsSelected = false;
                                    if (tempselectRow.Level != _selectRow.Level)
                                    {
                                        foreach (UserCell c in HeadColumns[_selectRow.Level].Cells)
                                        {
                                            c.IsSelect = false;
                                        }
                                    }
                                }
                            }
                            _selectRow = tempselectRow;
                            if (tempselectRow.ExpandEvent)
                            {
                                CalcMapSize();
    
                            }
                            this.pbImg.Refresh();
                        }
                    }
    
                }
            }
    
            UserCell SelectHeadIndex(float x, float y)
            {
                if (_selectRow != null)
                {
                    UserRow headrow = HeadColumns[_selectRow.Level];
                    if (headrow != null)
                    {
                        float margleft = _selectRow.calcMarginLeft(_selectRow);
                        float startPointX = margleft - MapLocationX;
                        foreach (UserCell c in headrow.Cells)
                        {                       
                            if (x >= startPointX && x <= startPointX + c.Width && y > 0 && y < rowHeight)
                            {
                                c.IsSelect = !c.IsSelect;
                                return c;
                            }
                            startPointX += c.Width;
                        }
                    }
                }
                return null;
            }
            UserRow SelectRow(float x, float y)
            {
                Console.WriteLine("选择坐标:x= " + x + " y= " + y);
                
                foreach (UserRow u1 in Rows)
                {
                    if (u1.IsSelect(x, y, rowHeight, rowWidth))
                    {
                        return u1;
                    }
                    else if (u1.Expand == true)
                    {
                        foreach (UserRow u2 in u1.SubRows)
                        {
                            if (u2.IsSelect(x, y, rowHeight, rowWidth))
                            {
                                return u2;
                            }
                            else if (u2.Expand)
                            {
                                foreach (UserRow u3 in u2.SubRows)
                                {
                                    if (u3.IsSelect(x, y, rowHeight, rowWidth))
                                    {
                                        return u3;
                                    }
                                }
                            }
                        }
                    }
                }
                return null;
            }
    
            private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
            {
                //System.Threading.Thread.Sleep(5);
                //MapLocationY = e.OldValue;
                //Console.WriteLine("old:" + e.OldValue);
                //Console.WriteLine("new:"+e.NewValue);
                //this.pbImg.Refresh();
                
            }
    
            private void hScrollBar1_Scroll(object sender, ScrollEventArgs e)
            {
                //MapLocationX = e.NewValue;
                //Console.WriteLine("new:" + e.NewValue);
                //this.pbImg.Refresh();
            }
    
            private void UserControl1_Resize(object sender, EventArgs e)
            {
            }
    
            private void pbImg_Resize(object sender, EventArgs e)
            {
                CalcMapSize();
                this.pbImg.Refresh();
            }
    
            private void vScrollBar1_ValueChanged(object sender, EventArgs e)
            {
                MapLocationY = vScrollBar1.Value;
                this.pbImg.Refresh();
            }
    
            private void hScrollBar1_ValueChanged(object sender, EventArgs e)
            {
                MapLocationX = hScrollBar1.Value;
                this.pbImg.Refresh();
            }
    
            private void 折叠层一ToolStripMenuItem_Click(object sender, EventArgs e)
            {
                foreach (UserRow u1 in Rows)
                {
                    u1.Expand = false;
                    
                }
                if (_selectRow != null && _selectRow.Level!= 0)
                {
                    _selectRow.Expand = false;
                }
                CalcMapSize();
                this.pbImg.Refresh();
            }
    
            private void 折叠层二ToolStripMenuItem_Click(object sender, EventArgs e)
            {
                foreach (UserRow u1 in Rows)
                {
                    foreach (UserRow u2 in u1.SubRows)
                    {
                        u2.Expand = false;
                        //foreach (UserRow u3 in u2.SubRows)
                        //{
    
                        //}
                    }
    
                }
                if (_selectRow != null && _selectRow.Level > 1)
                {
                    _selectRow.Expand = false;
                }
                CalcMapSize();
                this.pbImg.Refresh();
            }
    
            
    
            private void 展开层一ToolStripMenuItem_Click(object sender, EventArgs e)
            {
                foreach (UserRow u1 in Rows)
                {
                    u1.Expand = true;
                   
    
                }
                CalcMapSize();
                this.pbImg.Refresh();
            }
    
            private void 展开层二ToolStripMenuItem_Click(object sender, EventArgs e)
            {
                foreach (UserRow u1 in Rows)
                {
                    u1.Expand = true;
                    foreach (UserRow u2 in u1.SubRows)
                    {
                        u2.Expand = true;
                        //foreach (UserRow u3 in u2.SubRows)
                        //{
    
                        //}
                    }
    
                }
                CalcMapSize();
                this.pbImg.Refresh();
            }
        }
    }

    4 最后在FORM界面中使用

    首先需要生成数据源

    public List<UserRow> Rows = new List<UserRow>();
    
            SortedList<int, UserRow> HeadColumns = new SortedList<int, UserRow>();
    
    void BuildData()
            {
                for (int i = 0; i < 100; i++)
                {
                    UserRow u1 = Packdata(0, i.ToString());
                    u1.Expand = true;
                    for (int j = 0; j < 5; j++)
                    {
                        UserRow u2 = Packdata(1, i.ToString() + "-" + j.ToString());
                        u2.Parent = u1;
                        u2.Expand = true;
                        u1.SubRows.Add(u2);
    
                        for (int k = 0; k < 200; k++)
                        {
                            UserRow u3 = Packdata(2, i.ToString() + "-" + j.ToString() + "-" + k.ToString());
                            u3.Parent = u2;
                            u2.SubRows.Add(u3);
                        }
                    }
    
                    Rows.Add(u1);
                }
    
                HeadColumns.Add(0, PackHead(0));
                HeadColumns.Add(1, PackHead(1));
                HeadColumns.Add(2, PackHead(2));
            }
    
    UserRow Packdata(int level, string index)
            {
                UserRow u = new UserRow(level);
                for (int i = 0; i < 10; i++)
                {
                    UserCell cell = new UserCell();
                    cell.Value = index + "-" + i.ToString();
                    u.Cells.Add(cell);
                }
    
                return u;
            }
    
            UserRow PackHead(int level)
            {
                UserRow u = new UserRow(level);
                for (int i = 0; i < 10; i++)
                {
                    UserCell cell = new UserCell();
                    cell.Value = "" + level + "-" + i;
                    u.Cells.Add(cell);
                }
    
                return u;
            }

    最后把控件添加到form窗体中

    private void Form2_Load(object sender, EventArgs e)
            {
                BuildData();
                UserControl1 uct = new UserControl1(Rows);
                uct.HeadColumns = HeadColumns;
                this.Controls.Add(uct);
                uct.Dock = DockStyle.Fill;
            }

    DEMO代码虽然比较粗糙,但是不影响使用。

    转载麻烦指明出处。。。

  • 相关阅读:
    NET領域模型(1)
    oracle 函數索引(1)
    oracle 動態SQL(1)
    WF事件驱动(5)
    WF事件驱动(3)
    WF事件驱动(4)
    HP LoadRunner 11.00 新鲜尝
    Tomcat配置优化要点
    WebSphere性能诊断与调优
    性能测试工具、监控工具
  • 原文地址:https://www.cnblogs.com/mtxcat/p/14524158.html
Copyright © 2011-2022 走看看