图文详解!DevExpress XtraScheduler日程管理控件应用实例(1)-- 基本使用

在一些应用场景中,咱们可能须要记录某一天,某个时段的日程安排,那么这个时候就须要引入了 DevExpress 的日程控件XtraScheduler 了,这个控件功能很是强大,提供了很好的界面展示方式,以及不少的事件、属性给咱们定制修改,能很好知足咱们的日程计划安排的需求,本文全面分析并使用这 个控件,但愿把其中的经验与你们分享。html

当即下载DevExpress安装包,免费体验30天!数据库

一、日程控件的表现效果

整个日程控件,能够分为日视图、周视图、月视图等等,固然还有一些不经常使用的时间线、甘特图等,本例咱们来关注控件的使用以及这几个视图的处理。先来看看他们的界面效果,以下所示。微信

日视图:app

DevExpress日程控件

在视图里面,默承认以打开响应的日程事件进行编辑的。框架

DevExpress日程控件

周视图:ide

DevExpress日程控件

月视图:函数

DevExpress日程控件

二、日程控件XtraScheduler的使用

咱们在上面展现了这个控件的几个视图的界面,通常状况下的控件使用仍是很方便的,也就是直接拖拉SchedulerControl到Winform界面便可,可是咱们为了符合咱们的使用需求,仍是须要设置很多属性或者事件的处理的。工具

1)几种视图的切换

因为控件,默认也是提供右键菜单,对几种控件视图进行切换的,以下菜单所示。测试

DevExpress日程控件

可是咱们也能够经过代码进行切换处理,具体代码很简单,该控件已经进行了很好的封装,直接使用便可。this

[csharp] view plain copy

  1. private void btnDayView_Click(object sender, EventArgs e)  
  2.         {  
  3.             //须要为日视图类型  
  4.             this.schedulerControl1.ActiveViewType = SchedulerViewType.Day;  
  5.         }  
  6.   
  7.         private void btnWeekView_Click(object sender, EventArgs e)  
  8.         {  
  9.             //须要为周视图类型  
  10.             this.schedulerControl1.ActiveViewType = SchedulerViewType.FullWeek;  
  11.         }  
  12.   
  13.         private void btnMonthView_Click(object sender, EventArgs e)  
  14.         {  
  15.             //须要为周视图类型  
  16.             this.schedulerControl1.ActiveViewType = SchedulerViewType.Month;  
  17.         }  

2)设置禁用编辑、新增等功能处理

该日程控件,能够经过控件属性,对日程记录的新增、编辑、删除等菜单功能进行屏蔽或者开放(默认是开放的)。

经过控件属性的方式,操做以下所示。

DevExpress日程控件

固然咱们也能够经过代码对这些属性进行设置,以下代码所示。

[csharp] view plain copy

  1. SchedulerControl control = this.schedulerControl1;  
  2.   
  3.             //禁用日程增长、删除、修改、拖拉等操做  
  4.             control.OptionsCustomization.AllowAppointmentCreate = DevExpress.XtraScheduler.UsedAppointmentType.None;  
  5.             control.OptionsCustomization.AllowAppointmentDelete = DevExpress.XtraScheduler.UsedAppointmentType.None;  
  6.             control.OptionsCustomization.AllowAppointmentEdit = DevExpress.XtraScheduler.UsedAppointmentType.None;  
  7.             control.OptionsCustomization.AllowAppointmentDrag = DevExpress.XtraScheduler.UsedAppointmentType.None;  
  8.             control.OptionsCustomization.AllowAppointmentMultiSelect = false;  
  9.             control.OptionsRangeControl.AllowChangeActiveView = false;  
  10.             control.Views.MonthView.CompressWeekend = false;  
  11.             control.OptionsBehavior.ShowRemindersForm = false;  

3)日程控件的头部日期显示处理

默认的日程控件,其日视图、周视图的头部默认显示的是日期,以下所示。

DevExpress日程控件

若是须要把它修改成咱们想要的头部内容(如加上星期几),那么就须要对这个头部显示进行自定义的处理才能够了。

DevExpress日程控件

有两种方式能够实现这个功能, 其一是引入一个自定义类,以下所示。

[csharp] view plain copy

  1. public class CustomHeaderCaptionService : HeaderCaptionServiceWrapper  
  2.     {  
  3.         public CustomHeaderCaptionService(IHeaderCaptionService service)  
  4.             : base(service)  
  5.         {  
  6.         }  
  7.   
  8.         public override string GetDayColumnHeaderCaption(DayHeader header)  
  9.         {  
  10.             DateTime date = header.Interval.Start.Date;  
  11.             return string.Format("{0:M}({1})", date, date.ToString("dddd",new System.Globalization.CultureInfo("zh-cn")));  
  12.         }  
  13.     }  

而后在控件初始化后,添加对这个处理实现便可。

[csharp] view plain copy

  1. //重载头部显示  
  2.             IHeaderCaptionService headerCaptionService = (IHeaderCaptionService)control.GetService(typeof(IHeaderCaptionService));  
  3.             if (headerCaptionService != null)  
  4.             {  
  5.                 CustomHeaderCaptionService customHeaderCaptionService = new CustomHeaderCaptionService(headerCaptionService);  
  6.                 control.RemoveService(typeof(IHeaderCaptionService));  
  7.                 control.AddService(typeof(IHeaderCaptionService), customHeaderCaptionService);  
  8.             }  

或者也能够重载CustomDrawDayHeader事件进行修改处理,以下所示。(推荐采用上面一种)

[csharp] view plain copy

  1. private void schedulerControl1_CustomDrawDayHeader(object sender, CustomDrawObjectEventArgs e)  
  2.         {  
  3.             //重绘Header部分,设置日程头部显示格式  
  4.             SchedulerControl control = this.schedulerControl1;  
  5.             SchedulerViewType svt = control.ActiveViewType;  
  6.             if (svt == SchedulerViewType.Day || svt == SchedulerViewType.FullWeek ||  
  7.                 svt == SchedulerViewType.Week || svt == SchedulerViewType.WorkWeek)  
  8.             {  
  9.                 DayHeader header = e.ObjectInfo as DayHeader;  
  10.                 DateTime date = header.Interval.Start;  
  11.                 header.Caption = string.Format("{0}({1})", date.ToString("MM月d日"), date.ToString("dddd", new System.Globalization.CultureInfo("zh-cn")));  
  12.             }  
  13.         }  

4)自定义菜单的处理

在日程控件XtraScheduler的使用中,咱们也能够获取到控件的菜单对象,并对它进行修改、删除,或者新增本身的菜单事件也是能够的,咱们实现事件PopupMenuShowing便可,这个事件在菜单显示前进行处理,以下面所示代码。

[csharp] view plain copy

  1. private void schedulerControl1_PopupMenuShowing(object sender, PopupMenuShowingEventArgs e)  
  2.         {  
  3.             //对日程的右键菜单进行修改  
  4.             SchedulerControl control = this.schedulerControl1;  
  5.             if (e.Menu.Id == DevExpress.XtraScheduler.SchedulerMenuItemId.DefaultMenu)  
  6.             {  
  7.                 //隐藏【视图更改成】菜单  
  8.                 SchedulerPopupMenu itemChangeViewTo = e.Menu.GetPopupMenuById(SchedulerMenuItemId.SwitchViewMenu);  
  9.                 itemChangeViewTo.Visible = false;  
  10.   
  11.                 //删除【新建全部当天事件】菜单  
  12.                 e.Menu.RemoveMenuItem(SchedulerMenuItemId.NewAllDayEvent);  
  13.   
  14.                 //设置【新建按期日程安排】菜单为不可用  
  15.                 e.Menu.DisableMenuItem(SchedulerMenuItemId.NewRecurringAppointment);  
  16.   
  17.                 //更名【新建日程安排】菜单为自定义名称  
  18.                 SchedulerMenuItem item = e.Menu.GetMenuItemById(SchedulerMenuItemId.NewAppointment);  
  19.                 if (item != null) item.Caption = "新建一个计划";  
  20.   
  21.                 //建立一个新项,用内置的命令  
  22.                 ISchedulerCommandFactoryService service =  
  23.                     (ISchedulerCommandFactoryService)control.GetService(typeof(ISchedulerCommandFactoryService));  
  24.                 SchedulerCommand cmd = service.CreateCommand(SchedulerCommandId.PrintPreview);//打印预览  
  25.                 SchedulerMenuItemCommandWinAdapter menuItemCommandAdapter = new SchedulerMenuItemCommandWinAdapter(cmd);  
  26.                 DXMenuItem menuItem = (DXMenuItem)menuItemCommandAdapter.CreateMenuItem(DXMenuItemPriority.Normal);  
  27.                 menuItem.BeginGroup = true;  
  28.                 e.Menu.Items.Add(menuItem);  
  29.   
  30.                 //建立一个新的自定义事件菜单  
  31.                 DXMenuItem menuTest = new SchedulerMenuItem("测试菜单");  
  32.                 menuTest.Click += menuItem2_Click;  
  33.                 menuTest.BeginGroup = true;  
  34.                 e.Menu.Items.Add(menuTest);  
  35.             }  
  36.   
  37.         }  
  38.   
  39.         void menuItem2_Click(object sender, EventArgs e)  
  40.         {  
  41.             MessageDxUtil.ShowTips("测试菜单功能");  
  42.         }  

三、日程控件XtraScheduler的数据绑定

在日程控件里面,咱们最重要,最关注的莫过于它的数据绑定及内容显示了,由于只有这样,咱们才能够用于实价的应用当中,为用户显示他所需的数据,并存储咱们所须要的数据。

在日程控件里面,有相应的引导咱们进行这样的处理,仍是很是不错的。

数据的绑定,咱们须要了解日程控件的默认处理方式,由于它也提供了一些数据字段的信息,咱们从控件的对象里面,看到有建立数据库的信息,里面有一些 表的字段,咱们能够参考来建立咱们的数据存储信息,其中就包括了资源Resource的存储,日程事件安排Appointments的存储,以下所示。

DevExpress日程控件

根据这个里面的字段信息,咱们能够创建本身的数据库模型以下所示。

DevExpress日程控件

在数据库里面建立这两个表,并根据这些表对象,使用代码生成工具Database2Sharp进行代码的快速生成,而后复制生成的代码到具体的测试项目里面,生成的代码无需任何修改便可直接使用在具体项目里面,测试项目以下代码结构所示。

DevExpress日程控件

如日程资源对象的数据库信息,就会转换为具体的实体类信息,供咱们在界面中使用了,这样也符合个人Winform开发框架的实体类绑定规则,提升咱们数据的强类型约束。

如资源对象的实体类代码生成以下所示。

[csharp] view plain copy

  1. /// <summary>  
  2.     /// 日程资源  
  3.     /// </summary>  
  4.     [DataContract]  
  5.     public class AppResourceInfo : BaseEntity  
  6.     {  
  7.         /// <summary>  
  8.         /// 默认构造函数(须要初始化属性的在此处理)  
  9.         /// </summary>  
  10.         public AppResourceInfo()  
  11.         {  
  12.             this.ID = 0;  
  13.             this.ResourceId = 0;  
  14.             this.Color = 0;  
  15.             this.Image = new byte[] { };  
  16.         }  
  17.  
  18.         #region Property Members  
  19.   
  20.         [DataMember]  
  21.         public virtual int ID { get; set; }  
  22.   
  23.         /// <summary>  
  24.         /// 资源ID  
  25.         /// </summary>  
  26.         [DataMember]  
  27.         public virtual int ResourceId { get; set; }  
  28.   
  29.         /// <summary>  
  30.         /// 资源名称  
  31.         /// </summary>  
  32.         [DataMember]  
  33.         public virtual string ResourceName { get; set; }  
  34.   
  35.         /// <summary>  
  36.         /// 颜色  
  37.         /// </summary>  
  38.         [DataMember]  
  39.         public virtual int Color { get; set; }  
  40.   
  41.         /// <summary>  
  42.         /// 图形  
  43.         /// </summary>  
  44.         [DataMember]  
  45.         public virtual byte[] Image { get; set; }  
  46.   
  47.         /// <summary>  
  48.         /// 自定义  
  49.         /// </summary>  
  50.         [DataMember]  
  51.         public virtual string CustomField1 { get; set; }  
  52.  
  53.  
  54.         #endregion  
  55.   
  56.     }  

有了这些对象,咱们还须要作的就是绑定控件和保存控件数据到数据库里面的处理。

可是这里还须要注意一个问题就是,这个日程控件数据是经过字段映射的方式进行数据绑定的,也就是它自己也提供了几个常规字段的信息,所以咱们须要把它们的属性和数据库的字段(这里是实体类)的信息进行匹配。

如咱们能够经过绑定以下,事项Appointments和Resources的Mappings处理。

[csharp] view plain copy

  1. /// <summary>  
  2.         /// 设置日程控件的字段映射  
  3.         /// </summary>  
  4.         /// <param name="control">日程控件</param>  
  5.         private void SetMappings(SchedulerControl control)  
  6.         {  
  7.             AppointmentMappingInfo appoint = control.Storage.Appointments.Mappings;  
  8.             appoint.AllDay = "AllDay";  
  9.             appoint.Description = "Description";  
  10.             appoint.End = "EndDate";  
  11.             appoint.Label = "AppLabel";  
  12.             appoint.Location = "Location";  
  13.             appoint.RecurrenceInfo = "RecurrenceInfo";  
  14.             appoint.ReminderInfo = "ReminderInfo";  
  15.             appoint.ResourceId = "ResourceId";  
  16.             appoint.Start = "StartDate";  
  17.             appoint.Status = "Status";  
  18.             appoint.Subject = "Subject";  
  19.             appoint.Type = "EventType";  
  20.   
  21.             ResourceMappingInfo res = control.Storage.Resources.Mappings;  
  22.             res.Caption = "ResourceName";  
  23.             res.Color = "Color";  
  24.             res.Id = "ResourceId";  
  25.             res.Image = "Image";  
  26.         }  

肯定控件属性和实体类之间关系后,咱们就须要从数据库里面加载信息了。咱们在窗体的代码里面增长两个资源对象的集合列表,以下代码所示。

[csharp] view plain copy

  1. //日程资源集合和事件列表  
  2.        private List<AppResourceInfo> ResourceList = new List<AppResourceInfo>();  
  3.        private List<UserAppointmentInfo> EventList = new List<UserAppointmentInfo>();  

而后就是把数据从数据库里面,经过开发框架底层的工厂类进行数据的提取,以下代码所示。

[csharp] view plain copy

  1. private void btnLoadData_Click(object sender, EventArgs e)  
  2.         {  
  3.             //从数据库加载日程信息  
  4.             List<AppResourceInfo> resouceList = BLLFactory<AppResource>.Instance.GetAll();  
  5.             this.schedulerStorage1.Resources.DataSource = resouceList;  
  6.   
  7.             List<UserAppointmentInfo> eventList = BLLFactory<UserAppointment>.Instance.GetAll();  
  8.             this.schedulerStorage1.Appointments.DataSource = eventList;  
  9.   
  10.             if (resouceList.Count > 0)  
  11.             {  
  12.                 MessageDxUtil.ShowTips("数据加载成功");  
  13.             }  
  14.             else  
  15.             {  
  16.                 MessageDxUtil.ShowTips("数据库不存在记录");  
  17.             }  
  18.         }  

而保存数据,咱们把对象里面的集合存储到数据库里面便可。

[csharp] view plain copy

  1. private void btnSave_Click(object sender, EventArgs e)  
  2.         {  
  3.             int count = BLLFactory<AppResource>.Instance.GetRecordCount();  
  4.             if (count == 0)  
  5.             {  
  6.                 try  
  7.                 {  
  8.                     foreach (AppResourceInfo info in ResourceList)  
  9.                     {  
  10.                         BLLFactory<AppResource>.Instance.Insert(info);  
  11.                     }  
  12.   
  13.                     foreach (UserAppointmentInfo info in EventList)  
  14.                     {  
  15.                         BLLFactory<UserAppointment>.Instance.Insert(info);  
  16.                     }  
  17.   
  18.                     MessageDxUtil.ShowTips("数据保存成功");  
  19.                 }  
  20.                 catch (Exception ex)  
  21.                 {  
  22.                     LogTextHelper.Error(ex);  
  23.                     MessageDxUtil.ShowError(ex.Message);  
  24.                 }  
  25.             }  
  26.             else  
  27.             {  
  28.                 MessageDxUtil.ShowTips("数据库已存在数据");  
  29.             }  
  30.         }  

这样,经过代码工具Database2Sharp生成的代码,直接具备数据存储和获取的功能,例子就很容易明白和处理了,在实际的项目中,咱们可能 还须要存储用户的额外信息,如公司、部门、自定义信息等等,固然也能够经过这样的模式进行快速的开发,从而实现高效、统1、稳定的系统开发过程。

可是,言归正传,咱们前面介绍的字段,都是控件里面有的内容,若是是控件里面没有,咱们须要增长的自定义属性,那么咱们应该如何处理呢,还有默认的日程界面能够修改吗,等等这些也是咱们常常会碰到的问题。

首先咱们在日程控件界面上,经过链接按钮的方式,建立一个自定义的日程窗体,以下所示:

DevExpress日程控件

这样咱们就能够看到,在项目里面增长了一个日程编辑框了,打开窗体界面,并增长一个自定义的控件内容,最终界面以下所示。

DevExpress日程控件

默认的后台代码里面,具备了LoadFormData和SaveFormData两个重载的方法,这里就是留给咱们对自定义属性进行处理的方法体了。

咱们在其中增长部分自定义属性字段的映射处理便可,以下代码所示。

[csharp] view plain copy

  1. /// <summary>  
  2.         /// Add your code to obtain a custom field value and fill the editor with data.  
  3.         /// </summary>  
  4.         public override void LoadFormData(DevExpress.XtraScheduler.Appointment appointment)  
  5.         {                  
  6.             //加载自定义属性  
  7.             txtCustom.Text = (appointment.CustomFields["CustomField1"] == null) ? "" : appointment.CustomFields["CustomField1"].ToString();  
  8.   
  9.             base.LoadFormData(appointment);  
  10.         }  
  11.   
  12.         /// <summary>  
  13.         /// Add your code to retrieve a value from the editor and set the custom appointment field.  
  14.         /// </summary>  
  15.         public override bool SaveFormData(DevExpress.XtraScheduler.Appointment appointment)  
  16.         {  
  17.             //保存自定义属性  
  18.             appointment.CustomFields["CustomField1"] = txtCustom.Text;  
  19.   
  20.             return base.SaveFormData(appointment);  
  21.         }  

而后咱们记得在主体窗体的映射里面,为他们增长对应的字段映射便可,映射代码以下所示。

[csharp] view plain copy

  1. AppointmentCustomFieldMappingCollection appointCust = control.Storage.Appointments.CustomFieldMappings;  
  2.             appointCust.Add(new AppointmentCustomFieldMapping("CustomField1","CustomField1"));  

这样就构成了一个完整的映射信息。

[csharp] view plain copy

  1. /// <summary>  
  2.         /// 设置日程控件的字段映射  
  3.         /// </summary>  
  4.         /// <param name="control">日程控件</param>  
  5.         private void SetMappings(SchedulerControl control)  
  6.         {  
  7.             AppointmentMappingInfo appoint = control.Storage.Appointments.Mappings;  
  8.             appoint.AllDay = "AllDay";  
  9.             appoint.Description = "Description";  
  10.             appoint.End = "EndDate";  
  11.             appoint.Label = "AppLabel";  
  12.             appoint.Location = "Location";  
  13.             appoint.RecurrenceInfo = "RecurrenceInfo";  
  14.             appoint.ReminderInfo = "ReminderInfo";  
  15.             appoint.ResourceId = "ResourceId";  
  16.             appoint.Start = "StartDate";  
  17.             appoint.Status = "Status";  
  18.             appoint.Subject = "Subject";  
  19.             appoint.Type = "EventType";  
  20.   
  21.             AppointmentCustomFieldMappingCollection appointCust = control.Storage.Appointments.CustomFieldMappings;  
  22.             appointCust.Add(new AppointmentCustomFieldMapping("CustomField1","CustomField1"));  
  23.   
  24.             ResourceMappingInfo res = control.Storage.Resources.Mappings;  
  25.             res.Caption = "ResourceName";  
  26.             res.Color = "Color";  
  27.             res.Id = "ResourceId";  
  28.             res.Image = "Image";  
  29.         }  

以上就是我在整合日程控件XtraScheduler的经验总结,其中已经考虑了数据存储和显示,以及快速开发的几个方面,固然咱们能够根据这些案例,作出更好的日程应用来了。 

by 伍华聪

===============================================================

更多精彩预告请持续关注DevExpress中文网!

 扫描关注DevExpress中文网微信公众号,及时获取最新动态及最新资讯

DevExpress中文网微信

相关文章
相关标签/搜索