程序介绍


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

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



贴图图片
图一 主界面

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

贴图图片
图二

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


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


详细设计

监控数据源接口 IScheduleDataSource

贴图图片

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

    /// <summary>

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

    /// </summary>

    publicinterfaceIScheduleDataSource

    {

        /// <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.vjsdn.net 易学网

    }


定义一个基类实现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.vjsdn.net 易学网


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.vjsdn.net 易学网


重点介绍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.vjsdn.net 易学网


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.vjsdn.net 易学网



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值