使用Scheduler控件实现生产进度监控程序
作者:C/S框架网  发布日期:2011/07/13 22:15:29
使用Scheduler控件实现生产进度监控程序

使用DevExpress的Scheduler控件实现生产进度监控程序

有些网友说我发表文章太慢了,没有新的原创帖不够刺激,没有看头。我想问下您们:那么多帖子看完了没有?
学会了没有?再站在我的角度想: 原创啊,自己动手写的才算原创,要独一无二,要全中文网只有框架网才有。
但是,所有的一切需要时间,特别是那些有技术含量的帖,也许数日才发表一篇!

幸好这几天写了个生产进度监控程序,要不然交不了差,哈哈!这回没二话说了吧!

好了,转入正题:


程序介绍

近阶段参与开发某生产系统,应上级要求:boss要在自己的电脑前能看到工厂的订单情况,材料需求,
生产进度等动态信息。特别指定要像xxx系统那样图形化展示(boss参观的某系统),与同事们商量后
决定用功能强大且界面美观的Scheduler控件。我们分工合作,框架部分交于我处理了。通过2天努力
框架原型出来了,不敢独享,并特别制作一些UML图配合讲解发表出来。以供大家学习讨论。

接下来讲解框架实现,因口才及表达能力有限,有些地方不能言传只可意会。
当然,大部分内容需要自己理解了!



贴图图片

图一  主界面

说明:列出每月CI单(订毛单)收货情况。第页可显示5~30日数据,但选择天数越多表格越小也不利用
浏览。经测试,显示5~15日的数据最佳,用不同颜色表示到货状态,用ToolTip控件显示单据详细内容,
如百分比,到货日期等信息。用户可调整单元格高度来显示完整信息,测试时仅显示2行资料,所以调整
图形元素高度为33最适宜。

贴图图片
图二

说明:主界面封装在ucProduceScheduler用户控件内。如新建监控窗体拖放一个ucProduceScheduler
控件,设DockStyle为Fill。然后给控件指定一个数据源对象(实现IScheduleDataSource接口)


贴图图片
图三 生产进度监控程序完整视图


详细设计

监控数据源接口 IScheduleDataSource

贴图图片

该接口用于指定数据来源,ucProduceScheduler控件操作IScheduleDataSource提供的数据。
源代码如下:

    /// <summary>

    /// 生产进度监控台数据源接口

    /// </summary>

    public interface IScheduleDataSource

    {

        /// <summary>

        /// 数据表,原始数据

        /// </summary>

        DataTable DataSource { get; }

 

        /// <summary>

        /// 开始日期

        /// </summary>

        DateTime StartDate { get; }

 

        /// <summary>

        /// 将数据表转换成Appointment数组

        /// </summary>

        /// <param name="dayCount">只显示指定天数的数据</param>

        /// <returns></returns>

        Appointment[] ConvertAppointment(int dayCount);

 

        /// <summary>

        /// 跟据日期创建数据源

        /// </summary>

        IScheduleDataSource CreateDataSource(DateTime fromTime, DateTime toTime);

              //原创文章,如转载请注明出处。by www.csframework.com C/S框架网

    }


定义一个基类实现IScheduleDataSource接口,命名为ScheduleDataSourceBase.然后派生出n个子类,
n个子类代表n个数据来源,所以ucProduceScheduler通过控制接口实际上控制了所有数据来源。

贴图图片

/// <summary>
/// 数据源基类,实现IScheduleDataSource接口
/// </summary>
public class ScheduleDataSourceBase : IScheduleDataSource
{
   protected DataTable _DataSource;
   protected DateTime _StartDate;
   
   public ScheduleDataSourceBase(DataTable source, DateTime startDate)
   {
      _DataSource = source;
      _StartDate = startDate;
   }
   
   public virtual Appointment[] ConvertAppointment(int dayCount) { return null; }
   
   public DataTable DataSource { get { return _DataSource; } }
   public DateTime StartDate { get { return _StartDate; } }
   
   protected bool _IsGenerateFitField = false;
   
   /// <summary>
   /// 生成Schedule控件的TimeRuler时间分隔数据
   /// </summary>
   /// <param name="interval">分钟数:5,10,15</param>
   public void FitStartDate(int interval)
   {
      if (_IsGenerateFitField) return;
      
      
      _DataSource.Columns.Add(TScheduleData.IntervalField, typeof(DateTime));
      
      DateTime begin = new DateTime(_StartDate.Year, _StartDate.Month, _StartDate.Day);
      DateTime temp = DateTime.MinValue;
      DateTime last = DateTime.MinValue;
      DateTime increase = DateTime.MinValue;
      
      foreach (DataRow row in _DataSource.Rows)
      {
         //取单据的开始时间
         temp = DateTime.Parse(row[TScheduleData.StartTime].ToString());
         
         if (last != temp)
         {
            increase = temp;
            last = temp;
         }
         
         row[TScheduleData.IntervalField] = increase;
         increase = increase.AddMinutes(interval);
      }
      _DataSource.AcceptChanges();
      _IsGenerateFitField = true;
   }
   
   public virtual IScheduleDataSource CreateDataSource(DateTime fromTime, DateTime toTime) { return null; }
}
//原创文章,如转载请注明出处。by www.csframework.com C/S框架网


 

DevExpress.XtraScheduler.SchedulerControl 控件展示的所有元素是Appointment对象。
我们通过扩展Appointment对象来保存自定义的数据。如DataRow,ISID,DocNo等数据。
贴图图片


/// <summary>
/// 自定义预约基类(业务单数据展示基类)
/// </summary>
public class ScheduleItemBase : Appointment
{
   protected DataRow _DataRow;
   protected string _ISID;
   protected string _DocNo;
   protected int _StateValue;
   
   public ScheduleItemBase() { }
   public ScheduleItemBase(DataRow row)
   {
      _DataRow = row;
      this.ConvertToAppointment(row);
   }
   
   public DataRow DataRow { get { return _DataRow; } }
   public string ISID { get { return _ISID; } }
   public string DocNo { get { return _DocNo; } }
   public int StateValue { get { return _StateValue; } }
   private string _ToolTip = "";
   
   /// <summary>
   /// DataRow结构转换为Appointment对象
   /// </summary>
   /// <param name="row"></param>
   public virtual void ConvertToAppointment(DataRow row)
   {
      _ISID = row["ISID"].ToString();
      _DocNo = ConvertEx.ToString(row[TScheduleData.KeyValue]);
      _StateValue = ConvertEx.ToInt(row[TScheduleData.StateValue]);
      
      this.Start = DateTime.Parse(row[TScheduleData.IntervalField].ToString()); //用转换后的时间作为Start属性的值
      this.End = this.Start;//开始与结束时间相等
      this.Subject = ConvertEx.ToString(row[TScheduleData.Subject]);
      this.Location = ConvertEx.ToString(row[TScheduleData.Location]);
      this.LabelId = ConvertEx.ToInt(row[TScheduleData.ColorValue]);
      this.StatusId = ConvertEx.ToInt(row[TScheduleData.StateValue]);
      
      //建议DataTable返回Description字段
      this.Description = ConvertEx.ToString(row[TScheduleData.Subject]); ;
   }
   
   public string ToolTip
   {
      get
      {
         if (_ToolTip == "") _ToolTip = this.GetToolTip();
         return _ToolTip;
      }
   }
   
   /// <summary>
   /// 返回提示消息
   /// </summary>
   protected virtual string GetToolTip() { return ""; }
}
//原创文章,如转载请注明出处。by www.csframework.com C/S框架网


重点介绍ScheduleItemBase的ConvertToAppointment方法。

因数据来源最低层是DataTable对象,需要转换DataTable数据为Appointment[]才能在Scheduler控件内显示。该方法用于转换DataRow为Appointment对象。

另一个是FitStartDate(int interval)方法, 作用是调整DataTable数据源的StartTime字段的值,
interval参数指定分钟数。转换StartTime的数据保存在StartDateInterval字段,转换后的格式是:
(假设interval=15分钟)
2009-12-05 00:00:000
2009-12-05 00:15:000
2009-12-05 00:30:000
2009-12-05 00:45:000
2009-12-05 01:00:000
......

显示结果:
贴图图片


其它核心代码:

CIScheduleDataSource CI单(订毛单)数据源
该类是实现IScheduleDataSource接口的最终派生类。

/// <summary>
/// CI单数据源
/// </summary>
public class CIScheduleDataSource : ScheduleDataSourceBase
{
   public CIScheduleDataSource(DataTable source, DateTime startDate) : base(source, startDate) { }
   
   public override Appointment[] ConvertAppointment(int dayCount)
   {
      Exception.Equals(_DataSource, null);
      
      this.FitStartDate(15);//每15分钟时间线生成一条记录
      
      //转换数据.DataTable -> Appointment[]
      Appointment[] aps = new CIAppointment[_DataSource.Rows.Count];
      for (int i = 0; i <= _DataSource.Rows.Count - 1; i++)
      aps[i] = new CIAppointment(_DataSource.Rows[i]);
      
      return aps;
   }
   
   public override IScheduleDataSource CreateDataSource(DateTime fromTime, DateTime toTime)
   {
      DataTable dt = DemoDataSource.GetData();
      DateTime start = DateTime.Parse(dt.Rows[0][TScheduleData.StartTime].ToString());
      IScheduleDataSource source = new CIScheduleDataSource(dt, start);
      return source;
   }
}
//原创文章,如转载请注明出处。by www.csframework.com C/S框架网



CI单对象

/// <summary>
/// CI 单
/// </summary>
public class CIAppointment : ScheduleItemBase
{
   public CIAppointment() { }
   public CIAppointment(DataRow row) : base(row) { }
   
   /// <summary>
   /// 返回提示消息
   /// </summary>
   protected override string GetToolTip()
   {
      string html = "单号:{0}</br>日期:{1}</br>进度:{2}";
      DateTime docDate = DateTime.Parse(_DataRow[TScheduleData.StartTime].ToString());
      string Location = ConvertEx.ToString(_DataRow[TScheduleData.Location]);
      html = string.Format(html, _DocNo, docDate, Location);
      return html;
   }
   
   /// <summary>
   /// 如有特殊字段,重写该方法转换Appointment对象
   /// </summary>
   /// <param name="row"></param>
   public override void ConvertToAppointment(DataRow row)
   {
      base.ConvertToAppointment(row);
   }
}

//原创文章,如转载请注明出处。by www.csframework.com C/S框架网



Scheduler较复杂,这里不详细讲解了! 下载附件细细研究,我还要留时间发表其它文章。

系统需求:

vs 2008
dev express 2009 9.2x
sql express 2005
Sql连接字符串在DemoDataSource的GetData方法内修改.

点击下载附件 (VIP会员下载) 点击下载附件 (如下载失败,请邮件通知我们寄回给您,或QQ:23404761留言.)
上一篇 下一篇