使用GridVIew显示Gantt(甘特图),动态增减列

说明:本例是做了工厂的排机报表

一、根据查询日期初始化GridView列

private void IniGridView(DateTime p_DateS,DateTime p_DateE)
        {
            //1.移除机台以外的列 
            for (int i = gridView1.Columns.Count - 1; i >= 0; i--)//从后向前遍历删除,否则会引起混乱。不用foreach也是出于此原因
            {
                if (gridView1.Columns[i].FieldName != "MachineNo")//MachineNo:机台
                {
                    gridView1.Columns.RemoveAt(i);//移除
                }
            }

            //2.根据日期增加列
            //2-1.判断间隔长度
            TimeSpan TS1 = new TimeSpan(SysConvert.ToDateTime(p_DateS).Ticks);//SysConvert是我所使用框架自定义的,可更换为Convert
            TimeSpan TS2 = new TimeSpan(SysConvert.ToDateTime(p_DateE).Ticks);
            TimeSpan TS = TS1.Subtract(TS2).Duration();
            int days = TS.Days;

            if (days>100)//限制不要超出100天,防止用户误选过长日期,可根据实际情况调整
            {
                return;
            }
            //2-2.循环增加列
            for (int i = 0; i <= days; i++)
            {
                //定义列名为日期
                DateTime coldate = p_DateS.AddDays(i);
               
                //添加列
                DevExpress.XtraGrid.Columns.GridColumn column = new DevExpress.XtraGrid.Columns.GridColumn();
                column.FieldName = coldate.ToString("yyyy-MM-dd");//把日期作为字段名,此处需要特别注意,填充数据时,需要根据日期确定归属列
                column.Caption = coldate.ToString("M.dd");//显示名称
                column.Visible = true;//可见性
                column.VisibleIndex = i;//序号   必须设置,否则默认-1,仍然不可见
                column.ColumnEdit = this.txtMemo;
                gridView1.Columns.Add(column);
            } 
        }

二、处理DataTable

public override void BindGrid()
        { 
            string sql = "SELECT MachineNo FROM Data_MachineManage WHERE 1=1 ";  //   Data_MachineManage是存储所有机台的数据表     
            DataTable dt = SysUtils.Fill(sql);//SysUtils为框架特有方法,非普遍方法,视实际情况替换
            Proc(dt,txtFormDateS.DateTime,txtFormDateE.DateTime);
            gridView1.GridControl.DataSource = dt;
            gridView1.GridControl.Show();
        }

/// <summary>
/// 处理数据表,填充排机信息
/// </summary>
 /// <param name="dt"></param>
        private void Proc(DataTable p_dt,DateTime p_DateS,DateTime p_DateE)
        {
            //扩充dt表的列数与GridView列数一致
            TimeSpan TS1 = new TimeSpan(SysConvert.ToDateTime(p_DateS).Ticks);
            TimeSpan TS2 = new TimeSpan(SysConvert.ToDateTime(p_DateE).Ticks);
            TimeSpan TS = TS1.Subtract(TS2).Duration();
            int days = TS.Days;
            if (days>100)
            {
                return;
            }
            for (int i = 0; i <= days; i++)
            {
                DateTime coldate = p_DateS.AddDays(i);//取当天日期作为列名,与GridView保持一致
                p_dt.Columns.Add(coldate.ToString("yyyy-MM-dd"), typeof(string));//添加列
            }

            //根据数据来填格子
            string sql = "SELECT * FROM UV1_Sale_SOReviewPlan WHERE ProDate between ' "+p_DateS.toString()+" ' and ' "+p_DateE.toString()+" ' "; //说明:查询出的一条记录包含以下信息:日期ProDate,订单OrderFormNo,机台MachineNo。一条记录只包含一天的排机信息,10.1-10.5号是6条记录,而非一条
           
            DataTable dt = SysUtils.Fill(sql);//把符合条件的所有排机记录取出来
            foreach (DataRow dr in dt.Rows)
            {
                //定义显示字符串
                string str=dr["OrderFormNo"].ToString();
                
                //定义机台,方便查询
                string JT = dr["MachineNo"].ToString();

                //当前行的日期,以便确定属于p_dt表的哪一列
                string prodate = SysConvert.ToDateTime(dr["Prodate"]).ToString("yyyy-MM-dd");
                DataRow[] p_drarr = p_dt.Select("MachineNo=" + SysString.ToDBString(JT));//在排机表里把机台行取出来
                if (p_drarr.Length==0)//无此机台则中断本次循环
                {
                    continue;
                }
                else
                {
                    DataRow p_dr = p_drarr[0];//取出符合条件的第一行
                    p_dr[prodate] = str;//此处prodate为列名,GridView和p_dt中每个日期的字段均为某年某月某日
                }
            }
        }

附上效果图:

原文地址:https://www.cnblogs.com/luoxueningchen/p/4878812.html