This is a migrated thread and some comments may be shown as answers.

[Solved] Error Deleting Recurring Appointment Exception

2 Answers 300 Views
Scheduler
This is a migrated thread and some comments may be shown as answers.
zac
Top achievements
Rank 1
zac asked on 17 Jun 2008, 11:34 PM
Hi,

I have the scheduler largely working as it should - inserting and updating are working fine as is deleting stand-alone appointments and recurring series. The problem is when I try to delete an Exception - I get the error: "Cannot locate the parent of appointment with ID = 'x'. Ensure that the parent appointment with ID = 'x' exists and is loaded." I've performed a watch on the Scheduler control at the moment this error is being caught and can see the parent appointment with the right ID exists (It's a string datatype though - could this be the problem?).

So far as I can tell I'm doing everything by the book - saving on AppointmentInsert and AppointmentUpdate, deleting on AppointmentDelete. The error is being thrown after Page_Load (where I bind the scheduler control if it's not postback) but before it reaches the AppointmentDelete event handler. The code is attached.

    <asp:ScriptManager ID="scmEvents" runat="server" OnAsyncPostBackError="scmEvents_AsyncPostBackError" /> 
    <telerik:RadAjaxManager ID="ramEvents" runat="server"
        <AjaxSettings> 
            <telerik:AjaxSetting AjaxControlID="rscEvents"
                <UpdatedControls> 
                    <telerik:AjaxUpdatedControl ControlID="rscEvents" LoadingPanelID="ralEvents" /> 
                </UpdatedControls> 
            </telerik:AjaxSetting> 
        </AjaxSettings> 
    </telerik:RadAjaxManager> 
    <telerik:RadAjaxLoadingPanel ID="ralEvents" runat="server" Transparency="10" BackColor="#E0E0E0" InitialDelayTime="500"
        <asp:Image ID="imgLoading" runat="server" style="margin-top: 200px;" ImageUrl="" BorderWidth="0px" AlternateText="Loading..." /> 
    </telerik:RadAjaxLoadingPanel> 
    <telerik:RadScheduler ID="rscEvents" runat="server" Width="750px" Height="561px" style="margin: 0 auto;" Skin="Office2007" SelectedView="MonthView" ShowViewTabs="False" 
        OnAppointmentInsert="rscEvents_AppointmentInsert" OnAppointmentUpdate="rscEvents_AppointmentUpdate" OnAppointmentDelete="rscEvents_AppointmentDelete" OnAppointmentDataBound="rscEvents_AppointmentDataBound" 
        DataKeyField="EventId" DataSubjectField="EventName" DataStartField="StartDate" DataEndField="EndDate" DataRecurrenceField="RecurrenceRule"  
        DataRecurrenceParentKeyField="RecurrenceParentId" StartInsertingInAdvancedForm="True" StartEditingInAdvancedForm="True" DisplayRecurrenceActionDialogOnMove="True" EnableResourceEditing="False"
        <TimelineView UserSelectable="False" /> 
    </telerik:RadScheduler> 
     
    /// <summary> 
    /// I'm using a form of the MVP pattern which is why all of the event handlers look the way they do.  
    /// </summary> 
    public partial class Events : BasePage, IEventsView 
    { 
        #region Fields 
 
        private EventsPresenter presenter; 
 
        private int eventId = -1; 
        private string eventName = String.Empty; 
        private string eventDescription = String.Empty; 
        private DateTime startDate = DateTime.MinValue; 
        private DateTime endDate = DateTime.MinValue; 
        private string recurrenceRule = String.Empty; 
        private string recurrenceParentId = String.Empty; 
        #endregion 
        #region Constructor 
 
        /// <summary> 
        /// Initializes a new instance of the <see cref="Events"/> class. 
        /// </summary> 
        public Events() 
        { 
            presenter = new EventsPresenter( thisnew EventsDataService(), DefaultInjection.GetDefault() ); 
            presenter.Init(); 
        } 
        #endregion 
        #region Events 
 
        /// <summary> 
        /// Occurs when the form is loaded 
        /// </summary> 
        public event EventHandler FormLoad; 
 
        /// <summary> 
        /// Occurs when an appointment is inserted. 
        /// </summary> 
        public event EventHandler AppointmentInsert; 
 
        /// <summary> 
        /// Occurs when an appointment is updated. 
        /// </summary> 
        public event EventHandler AppointmentUpdate; 
 
        /// <summary> 
        /// Occurs when an appointment is deleted. 
        /// </summary> 
        public event EventHandler AppointmentDelete; 
        #endregion 
        #region Event Handlers 
         
        protected void Page_Load( object sender, EventArgs e ) 
        { 
            if ( !IsPostBack ) 
            { 
                if ( FormLoad != null ) 
                { 
                    FormLoad( sender, e ); 
                } 
            } 
        } 
 
        protected void rscEvents_AppointmentInsert( object sender, SchedulerCancelEventArgs e ) 
        { 
            SetAppointmentDetails( e.Appointment ); 
 
            if ( AppointmentInsert != null ) 
            { 
                AppointmentInsert( sender, e ); 
            } 
        } 
 
        protected void rscEvents_AppointmentUpdate( object sender, AppointmentUpdateEventArgs e ) 
        { 
            SetAppointmentDetails( e.ModifiedAppointment ); 
 
            if ( AppointmentUpdate != null ) 
            { 
                AppointmentUpdate( sender, e ); 
            } 
        } 
 
        /// <summary> 
        /// The startDate is used to calculate the beginning date of the schedule 
        /// </summary> 
        protected void rscEvents_AppointmentDelete( object sender, SchedulerCancelEventArgs e ) 
        { 
            eventId = Int32.Parse( e.Appointment.ID.ToString() ); 
            startDate = e.Appointment.Start; 
 
            if ( AppointmentDelete != null ) 
            { 
                AppointmentDelete( sender, e ); 
            } 
        } 
 
        protected void rscEvents_AppointmentDataBound( object sender, SchedulerEventArgs e ) 
        { 
            e.Appointment.ToolTip = e.Appointment.Subject; 
        } 
 
        /// <summary> 
        /// Captures assynchronous exceptions and handles them in the same way as normal exceptions. 
        /// </summary> 
        protected void scmEvents_AsyncPostBackError( object sender, AsyncPostBackErrorEventArgs e ) 
        { 
            throw e.Exception; 
        } 
        
        #endregion 
        
        #region Properties 
         
        /// <summary> 
        /// This property is set by the Presenter when binding the scheduler control. 
        /// </summary> 
        public List<EventDTO> CurrentEvents 
        { 
            set 
            { 
                List<AppointmentDTO> appointments = new List<AppointmentDTO>(); 
 
                foreach ( EventDTO evnt in value ) 
                { 
                    appointments.Add( new AppointmentDTO( evnt ) ); 
                } 
 
                rscEvents.DataSource = appointments; 
                rscEvents.DataBind(); 
            } 
        } 
 
        public int EventId 
        { 
            get { return eventId; } 
        } 
 
        public string EventName 
        { 
            get { return eventName; } 
        } 
 
        public string EventDescription 
        { 
            get { return eventDescription; } 
        } 
 
        public DateTime StartDate 
        { 
            get { return startDate; } 
        } 
 
        public DateTime EndDate 
        { 
            get { return endDate; } 
        } 
 
        public string RecurrenceRule 
        { 
            get { return recurrenceRule; } 
        } 
 
        public string ReccurenceParentId 
        { 
            get { return recurrenceParentId; } 
        } 
        #endregion 
 
        /// <summary> 
        /// The fields being set in this method are used by the Presenter when saving appointments to the database. 
        /// </summary> 
        private void SetAppointmentDetails( Appointment appointment ) 
        { 
            eventId = appointment.ID != null ? Int32.Parse( appointment.ID.ToString() ) : -1; 
 
            eventName = appointment.Subject; 
            startDate = appointment.Start; 
            endDate = appointment.End; 
            recurrenceRule = appointment.RecurrenceRule; 
 
            if ( appointment.RecurrenceParentID != null && !String.IsNullOrEmpty( appointment.RecurrenceParentID.ToString() ) ) 
            { 
                recurrenceParentId = appointment.RecurrenceParentID.ToString(); 
            } 
        } 
        #region Classes 
 
        /// <summary> 
        /// Extends the base EventDTO to accomodate functionality in the Telerik Scheduler control by incorporating the RecurrenceState property and  
        /// making RecurrenceRule and RecurrenceParentId nullable. 
        /// </summary> 
        private class AppointmentDTO : EventDTO 
        { 
            #region Fields 
 
            private RecurrenceState recurrenceState; 
            #endregion 
            #region Constructors 
 
            private AppointmentDTO() 
            { 
                eventId = -1; 
            } 
 
            public AppointmentDTO( int eventId, string eventName, string eventDescription, DateTime startDate, DateTime endDate, string recurrenceRule, string recurrenceParentId ) : this() 
            { 
                this.eventId = eventId; 
                this.eventName = eventName; 
                this.eventDescription = eventDescription; 
                this.startDate = startDate; 
                this.endDate = endDate; 
                this.recurrenceRule = String.IsNullOrEmpty( recurrenceRule ) ? null : recurrenceRule; 
                this.recurrenceParentId = String.IsNullOrEmpty( recurrenceParentId ) ? null : recurrenceParentId; 
 
                if ( recurrenceParentId != null ) 
                { 
                    recurrenceState = RecurrenceState.Exception; 
                } 
                else if ( !String.IsNullOrEmpty( recurrenceRule ) ) 
                { 
                    recurrenceState = RecurrenceState.Occurence; 
                } 
            } 
 
            public AppointmentDTO( EventDTO evnt ) : this( evnt.EventId, evnt.EventName, evnt.EventDescription, evnt.StartDate, evnt.EndDate, evnt.RecurrenceRule, evnt.RecurrenceParentId ) { } 
            #endregion 
            #region Properties 
 
            /// <summary> 
            /// This is being setup as per the Binding Generic List demo but it never gets consumed - something I'm missing here??? 
            /// </summary> 
            public RecurrenceState RecurrenceState 
            { 
                get { return recurrenceState; } 
                set { recurrenceState = value; } 
            } 
            #endregion 
        } 
        #endregion 
    } 

I know that you can't see how the deletes, updates and inserts are actually being implemented because I haven't included the lower layers dealing with the business logic and data access but they are all working as they're supposed to.

Any help will be greatly appreciated. Thanks.

2 Answers, 1 is accepted

Sort by
0
Accepted
T. Tsonev
Telerik team
answered on 18 Jun 2008, 05:12 PM
Hi,

The different type definitely is a problem. At the moment EventID in your DTO is of type integer and the RecurrenceParentID is of type string. In a normal database scenario RecurrenceParentID will be a foreign key pointing to the EventID. Just changing the type to integer too should solve this issue.

Also, you do not need to use Int32.Parse, casting to int directly is just as safe in your scenario.

Regarding the RecurrenceState property - you are correct, it is redundant. RadScheduler will assign a recurrence state based on the values of the RecurrenceRule and RecurrenceParentID properties. We will update our example to reflect that.

I hope this helps.

All the best,
Tsvetomir Tsonev
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
0
zac
Top achievements
Rank 1
answered on 18 Jun 2008, 09:19 PM
Hi Tsvetomir,

The data type was the problem as you suggested. Thanks.

Point taken with the parse/cast as well.

Cheers,
Zac
Tags
Scheduler
Asked by
zac
Top achievements
Rank 1
Answers by
T. Tsonev
Telerik team
zac
Top achievements
Rank 1
Share this question
or