文档章节

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

Miss_Hello_World
 Miss_Hello_World
发布于 2018/02/13 10:49
字数 2953
阅读 41
收藏 0

在一些应用场景中,我们可能需要记录某一天,某个时段的日程安排,那么这个时候就需要引入了 DevExpress 的日程控件XtraScheduler 了,这个控件功能非常强大,提供了很好的界面展现方式,以及很多的事件、属性给我们定制修改,能很好满足我们的日程计划安排的需求,本文全面分析并使用这 个控件,希望把其中的经验与大家分享。

立即下载DevExpress安装包,免费体验30天!

1、日程控件的表现效果

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

日视图:

DevExpress日程控件

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

DevExpress日程控件

周视图:

DevExpress日程控件

月视图:

DevExpress日程控件

2、日程控件XtraScheduler的使用

我们在上面展示了这个控件的几个视图的界面,一般情况下的控件使用还是很方便的,也就是直接拖拉SchedulerControl到Winform界面即可,但是我们为了符合我们的使用需求,还是需要设置不少属性或者事件的处理的。

1)几种视图的切换

由于控件,默认也是提供右键菜单,对几种控件视图进行切换的,如下菜单所示。

DevExpress日程控件

但是我们也可以通过代码进行切换处理,具体代码很简单,该控件已经进行了很好的封装,直接使用即可。

[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.         }  

3、日程控件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生成的代码,直接具有数据存储和获取的功能,例子就很容易明白和处理了,在实际的项目中,我们可能 还需要存储用户的额外信息,如公司、部门、自定义信息等等,当然也可以通过这样的模式进行快速的开发,从而实现高效、统一、稳定的系统开发过程。

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

首先我们在日程控件界面上,通过连接按钮的方式,创建一个自定义的日程窗体,如下所示:

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中文网微信

本文转载自:

Miss_Hello_World
粉丝 22
博文 668
码字总数 404202
作品 0
九龙坡
私信 提问
DevExpress VCL Controls v15.1.5正式发布[附下载]

DevExpress VCL Controls是Devexpress公司旗下用户界面产品套包,包含该公司所有VCL控件产品和 ASP.NET控件产品以及相关产品的完整源码。所包含的控件有:数据录入,图表,数据分析,导航,布...

Miss_Hello_World
2015/10/12
258
0
2015年DevExpress资源汇总(文档、视频、Demo、更新)

原文:http://devexpresscn.com/Resources/Documentation-513.html DevExpress v15.1更新说明 | PDF完整版文档下载 【DevExpress v15.1新版亮点】DevExtreme控件升级(一) 【DevExpress v1......

百mumu
2016/01/11
242
0
用DevExpress做界面开发:惊艳的WPF界面框架 | 附安装程序

DevExpress WPF Controls拥有超过85个优选的界面控件和库,帮助你创建强大而优美的商业解决方案,并且满足最终用户最高要求的性能标准。 下载Universal安装包就可以马上体验这些示例哦! 注意...

百mumu
2015/11/11
7.1K
0
2014年DevExpress使用教程合集

DevExpress系列教程 DevExpress Universal Subscription是DevExpress旗下重要的用户界面控件,也是全球使用最多的.NET用户界面控件套包。自2014年以来,慧都小编为大家奉献了很多使用教程。如...

咲晚杍
2014/12/31
2.4W
1
【版本升级】VCL界面控件DevExpress VCL发布v17.2.6|附下载

DevExpress VCL Controls是 Devexpress公司旗下最老牌的用户界面套包。所包含的控件有:数据录入,图表,数据分析,导航,布局,网格,日程管理,样式,打印和工作流等,让您快速开发出完美、...

Miss_Hello_World
2018/04/13
66
0

没有更多内容

加载失败,请刷新页面

加载更多

如何查看Android的系统版本?

有谁知道我怎么能检查系统版本(例如1.0 , 2.2 ,等)编程? #1楼 我无法对答案发表评论,但是Kaushik的答案存在一个严重错误:SDK_INT与系统版本不同,但实际上是指API级别。 if(Build.VER...

技术盛宴
48分钟前
35
0
引入AI变量,精准农业正在加速豹变?

  不久前,“江苏省脱贫率达 99.99%,尚未脱贫人数仅剩 6 户、17 人”这样一则新闻刷屏。“把这 17 个人迁出,江苏就全省脱贫”、“最后这 6 户人家拖了后腿”,在网民们的调侃和质疑声背后...

水果黄瓜
51分钟前
41
0
Elasticsearch系列---结构化搜索

概要 结构化搜索针对日期、时间、数字等结构化数据的搜索,它们有自己的格式,我们可以对它们进行范围,比较大小等逻辑操作,这些逻辑操作得到的结果非黑即白,要么符合条件在结果集里,要么...

清茶豆奶
今天
69
0
每天AC系列(一):三数之和

1 题目 LeetCode第15题,难度中等,题目描述: 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。 注意:答...

Blueeeeeee
今天
120
0
OSChina 周四乱弹 —— 水果你们都没吃全

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @ 莱布妮子:分享五月天的单曲《温柔》@小小编辑 @cIouddyy @clouddyy 《温柔》- 五月天 手机党少年们想听歌,请使劲儿戳(这里) @FalconChe...

小小编辑
今天
1.9K
11

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部