圖文詳解!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中文網微信

相關文章
相關標籤/搜索