How to: Bind ASPxScheduler Appointment to ObjectDataSource

  • 10 min to read

This document demonstrates how to implement an object data source for use with the ASPxScheduler control.

To create an Object Data Source for appointments and bind it to theASPxScheduler instance, follow the instructions below.

Step 1. Create a Web Site

  1. Create a new Web Site in Visual Studio. In the File menu, click New, and then click Web Site. In the New Web Site dialog box that is invoked, click ASP.NET Empty Web Site.

    NewWebSiteCreating.png

  2. In the Website menu, click Add New Item. Select Web Form, leave the default name as is, and click Add.

    AddNewForm.png

  3. Switch to the Design View of the Default.aspx page, and drag the ASPxScheduler control from the DX.19.2: Scheduling Toolbox tab to the page.

Step 2. Create Classes for the Appointments Object Data Source

  1. In the Website menu, click Add ASP.NET Folder, and then click App_Code.
  2. In the Solution Explorer, right-click the App_Code folder, and then select New | Add New Item.
  3. In the Add New Item dialog box, select the Class template, specify its name as CustomEvents, and click Add. This class will contain all necessary properties for an appointment in the ASPxSchedulerStorage.Appointments collection. The property set is used in standard default mappings when the ASPxSchedulerStorage fetches data from the data source, or the appointment editing form posts data back to the storage.

    AddNewClass.png

  4. Create a collection of CustomEvent elements based on a generic System.ComponentModel.BindingList<T> class, which provides data binding.
  5. Provide methods for interaction with the ObjectDataSource control. The sole purpose of the CustomEventDataSource class is to provide an implementation of the insert, select, delete and update behaviors that will be called by the ObjectDataSource.

    This code snippet implements the object data source used for binding to the ASPxScheduler. Note that while other properties of a custom object are mapped in the application to regular appointment properties, the Price and ContactInfo fields should be mapped to appointment's PersistentObject.CustomFields.

    using System.ComponentModel;
    using System.Collections;
    [Serializable]
    public class CustomEvent {
        object id;
        DateTime start;
        DateTime end;
        string subject;
        int status;
        string description;
        long label;
        string location;
        bool allday;
        int eventType;
        string recurrenceInfo;
        string reminderInfo;
        object ownerId;
        double price;
        string contactInfo;
    
        public CustomEvent() {
        }
    
        public DateTime StartTime { get { return start; } set { start = value; } }
        public DateTime EndTime { get { return end; } set { end = value; } }
        public string Subject { get { return subject; } set { subject = value; } }
        public int Status { get { return status; } set { status = value; } }
        public string Description { get { return description; } set { description = value; } }
        public long Label { get { return label; } set { label = value; } }
        public string Location { get { return location; } set { location = value; } }
        public bool AllDay { get { return allday; } set { allday = value; } }
        public int EventType { get { return eventType; } set { eventType = value; } }
        public string RecurrenceInfo { get { return recurrenceInfo; } set { recurrenceInfo = value; } }
        public string ReminderInfo { get { return reminderInfo; } set { reminderInfo = value; } }
        public object OwnerId { get { return ownerId; } set { ownerId = value; } }
        public object Id { get { return id; } set { id = value; } }
        public double Price { get { return price; } set { price = value; } }
        public string ContactInfo { get { return contactInfo; } set { contactInfo = value; } }
    }
    [Serializable]
    public class CustomEventList : BindingList<CustomEvent> {
        public void AddRange(CustomEventList events) {
            foreach(CustomEvent customEvent in events)
                this.Add(customEvent);
        }
        public int GetEventIndex(object eventId) {
            for(int i = 0; i < Count; i++)
                if(this[i].Id == eventId)
                    return i;
            return -1;
        }
    }
    
    public class CustomEventDataSource {
        CustomEventList events;
        public CustomEventDataSource(CustomEventList events) {
            if(events == null)
                DevExpress.XtraScheduler.Native.Exceptions.ThrowArgumentNullException("events");
            this.events = events;
        }
        public CustomEventDataSource()
            : this(new CustomEventList()) {
        }
        public CustomEventList Events { get { return events; } set { events = value; } }
        public int Count { get { return Events.Count; } }
    
        #region ObjectDataSource methods
        public object InsertMethodHandler(CustomEvent customEvent) {
            Object id = customEvent.GetHashCode();
            customEvent.Id = id;
            Events.Add(customEvent);
            return id;
        }
        public void DeleteMethodHandler(CustomEvent customEvent) {
            int eventIndex = Events.GetEventIndex(customEvent.Id);
            if(eventIndex >= 0)
                Events.RemoveAt(eventIndex);
        }
        public void UpdateMethodHandler(CustomEvent customEvent) {
            int eventIndex = Events.GetEventIndex(customEvent.Id);
            if(eventIndex >= 0) {
                Events.RemoveAt(eventIndex);
                Events.Insert(eventIndex, customEvent);
            }
        }
        public IEnumerable SelectMethodHandler() {
            CustomEventList result = new CustomEventList();
            result.AddRange(Events);
            return result;
        }
        #endregion
    
        public object ObtainLastInsertedId() {
            if(Count < 1)
                return null;
            return Events[Count - 1].Id;
        }
    }
    

Step 3. Create an ObjectDataSource Control

  1. Switch to the page in which the ASPxScheduler control is located, and drag the ObjectDataSource control from the Data Toolbox tab to the page. Change the ID property of the control to appointmentDataSource.
  2. Click the smart tag of the control, and select the Configure Data Source item. In the Configure Data Source window, select CustomEventDataSource as the business object, and click Next.

    ChooseBusinessObject.png

  3. In the next panel, select the SelectMethodHandler method from the Choose a method drop-down list.

    DefineDataMethods.png

    Switch to the other tabs, and specify the following methods: UpdateMethodHandler for the Update tab, InsertMethodHandler for the Insert tab, and DeleteMethodHandler for the Delete tab. Click Finish.

    The ObjectDataSource is now configured for the CustomEvent objects.

  4. Next, bind the ASPxScheduler to the ObjectDataSource control by setting its AppointmentDataSourceID property to appointmentDataSource in the Property window.

Step 4. Set Up the Appointment Mappings

  1. Next, set up mappings for the appointments fields. To do this, locate the < dx: ASPxScheduler > opening and closing tags in the Default.aspx file. Add the following code between them:

            <dx:ASPxScheduler ID="ASPxScheduler1" runat="server" AppointmentDataSourceID="appointmentDataSource"  ClientIDMode="AutoID" 
                OnAppointmentRowInserted="ASPxScheduler1_AppointmentRowInserted">
                <Storage>
                    <Appointments>
                        <Mappings AppointmentId="Id" Start="StartTime" End="EndTime" Subject="Subject" AllDay="AllDay"
                            Description="Description" Label="Label" Location="Location" RecurrenceInfo="RecurrenceInfo"
                            ReminderInfo="ReminderInfo" Status="Status" Type="EventType" />
                    </Appointments>
                </Storage>
    
    <Views>
    <DayView><TimeRulers>
    <dx:TimeRuler></dx:TimeRuler>
    </TimeRulers>
    </DayView>
    
    <WorkWeekView><TimeRulers>
    <dx:TimeRuler></dx:TimeRuler>
    </TimeRulers>
    </WorkWeekView>
    </Views>
            </dx:ASPxScheduler>
    

Step 5. Implement Methods Required for Proper Binding

  1. To set the appointment ID in the ASPxScheduler storage, create the ASPxScheduler1_AppointmentRowInserted method, which obtains the ID of the last inserted appointment from the object data source, and assigns it to the appointment in the ASPxScheduler storage. To populate the ObjectDataSource control with data, handle the System.Web.UI.WebControls.ObjectDataSource.ObjectCreated event, which is fired when the control is created:

        CustomEventDataSource objectInstance;
    // Obtain the ID of the last inserted appointment from the object data source and assign it to the appointment in the ASPxScheduler storage.
        protected void ASPxScheduler1_AppointmentRowInserted(object sender, DevExpress.Web.ASPxScheduler.ASPxSchedulerDataInsertedEventArgs e) {
            e.KeyFieldValue = this.objectInstance.ObtainLastInsertedId();
        }
    
        protected void appointmentsDataSource_ObjectCreated(object sender, ObjectDataSourceEventArgs e) {
            this.objectInstance = new CustomEventDataSource(GetCustomEvents());
            e.ObjectInstance = this.objectInstance;
        }
        CustomEventList GetCustomEvents() {
            CustomEventList events = Session["CustomEventListData"] as CustomEventList;
            if(events == null) {
                events = new CustomEventList();
                Session["CustomEventListData"] = events;
            }
            return events;
        }
    
  2. Switch to the Design View of the Default.aspx page, and select the ObjectDataSource component. Subscribe the ObjectCreated event to the appointmentsDataSource_ObjectCreated event handler.
  3. Select the ASPxScheduler component. Subscribe the AppointmentRowInserted event to the ASPxScheduler1_AppointmentRowInserted event handler.

Result

Run the project. Make sure that you can create, delete and edit appointments.

SchedulerAtRunTime.png