How to add validation code to appointement change ?

6 posts, 0 answers
  1. Marco
    Marco avatar
    87 posts
    Member since:
    Apr 2011

    Posted 19 Aug 2013 Link to this post

    Hello Telerik

    I need your help for a particular point in using the RadScheduler.

    The appointement displayed in my Scheduler should start and end at some specific time values. The start time should be(08:00;10:00;13:00;15:00) and the end time should be (10:00;12:00;15:00;17:00).

    When an user modify one appointement (in all way), I want to check if the start and end times are correct. If not the value should be round to the nearest legal value (cancelling the operation with a message box is also an acceptable solution).

    Exemple: If the user set the start time to 9:00 the value is corrected to 08:00.

    I have tried to use the Appointements.CollectionChanged event of the Scheduler to change this. But if I correct the value at this time, the scheduler does not update correctly. (The text inside the appointement is changed but not the graphique square. You can see it in the attachement). How could I fix it?

    As adding validation rules in a changed event is never a good idea. If you know a way to prevent the user draging or realesing the mouse at an illegal time. It will be perfect !
  2. Dimitar
    Admin
    Dimitar avatar
    1411 posts

    Posted 22 Aug 2013 Link to this post

    Hi Marco,

    Thank you for writing.

    To achieve the desired functionality you can use a combination of the following events.
    • First instead of using Appointements.CollectionChanged event you can use Appointements.CollectionChanging event, this way the scheduler will be updated correctly. 
    • Second for the resizing you can use the appointment MouseUp event to set the appointment valid start and end times:
    void radScheduler1_AppointmentMouseUp(object sender, SchedulerAppointmentMouseEventArgs e)
    {
        Appointment appointment = e.Appointment as Appointment;
     
        if (appointment != null)
        {
            if (e.Appointment.Start.Hour != 8)
            {
                DateTime temp = appointment.StartDateTime;
     
                appointment.Start = new DateTime(temp.Year, temp.Month, temp.Day, 8, temp.Minute, temp.Second);
               
            }
        }
    }

    • Third you can use the AppointmentDropping event to prevent the user to drop the appointment in particular time frame:
    void radScheduler1_AppointmentDropping(object sender, Telerik.WinControls.UI.AppointmentMovingEventArgs e)
    {
         
        if (e.NewDate.Hour != 8)
        {
            RadMessageBox.Show("cannot drop here");
            e.Cancel = true;
        }
    }

    I hope this will be useful. Should you have further questions, I would be glad to help.

    Regards,
    Dimitar
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WINFORMS.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Marco
    Marco avatar
    87 posts
    Member since:
    Apr 2011

    Posted 22 Aug 2013 Link to this post

    Hi Dimitar,

     

    Thank you for writing your answer. I have tried your different solution and here are my conculsion:

    First - Appointments.CollectionChanging

    I don't know why, but in my project this event is never raised ! Does it work on your side ?

    Second - Scheduler.AppointmentMouseUp Event

    It looks like the AppointementMouseUp Event is raised after then Appointments.CollectionChanged event. As I try to save the change to my database in this event, there is a short time where the data could be incorrect (in fact my database raise an exception if the value is not legal). I have a exception on the Appointments.CollectionChanged, then values are checked in the AppointementMouseUp event, finally the change are saved.

    Don't know if I should use a boolean flag set on mousedown to prevent this exception. As the visual object of an appointement is stuck to ruler value. It Could be a solution to change this behavior. (I don't think that's a simple task :-))

    Third - Scheduler.AppointementDropping Event

    It's a good solution. Many thank ! I add a event Handler on the AppointementDropped Event to round the End of the dropped Appointement   to the nearest legal value. I notice that the Appointments.CollectionChanged event do not raise when I do a drop operation. As I set the end value with my rounding operation, this event is finally raised. Don't know if it is the desired behavior.

  5. Dimitar
    Admin
    Dimitar avatar
    1411 posts

    Posted 27 Aug 2013 Link to this post

    Hello Marco,

    Thank you for writing back.

    The CollectionChanging event is fired only when a appointment is added or removed from the AppointmentsCollection. In my opinion it would be best to use the CollectionChanged event for handling edit, add and resize of appointments. Follows modified version of my previous code to reflect your remarks. What it does is to correct the appointment start and end times when adding and to correct the appointment start time when resizing:
    bool isResizing = false;
     
    void radScheduler1_AppointmentResized(object sender, AppointmentResizedEventArgs e)
    {
        isResizing = true;
    }
     
    void Appointments_CollectionChanged(object sender, Telerik.WinControls.Data.NotifyCollectionChangedEventArgs e)
    {
     
        Appointment appointment = e.NewItems[0] as Appointment;
     
        if (appointment != null)
        {
            if (e.Action != NotifyCollectionChangedAction.Batch)
            {
                // all actions that differ from bach have a new item colection
                if (isResizing == false && appointment.StartDateTime.Hour != 8 && appointment.End.Hour != 12)
                {
                    DateTime temp = appointment.StartDateTime;
     
                    appointment.Start = new DateTime(temp.Year, temp.Month, temp.Day, 8, temp.Minute, temp.Second);
     
                    temp = appointment.End;
                    appointment.End = new DateTime(temp.Year, temp.Month, temp.Day, 12, temp.Minute, temp.Second);
                }
                else
                {
                    if (appointment.Start.Hour != 8)
                    {
                        DateTime temp = appointment.StartDateTime;
     
                        appointment.Start = new DateTime(temp.Year, temp.Month, temp.Day, 8, temp.Minute, temp.Second);
                    }
     
                    isResizing = false;
                }
            }
            else
            {
                // when we have a bach operation we must validate all apontments
                foreach (Appointment app in radScheduler1.Appointments)
                {
                    if (app.Start.Hour != 8)
                    {
                        DateTime temp = appointment.StartDateTime;
     
                        app.Start = new DateTime(temp.Year, temp.Month, temp.Day, 8, temp.Minute, temp.Second);
                    }
                }
            }
                         
        }
        radScheduler1.SchedulerElement.Refresh();
    }

    Also when you do drop operations the CollectionChanged event is fired with a batch action. Batch action is returned when several actions have been made at once for example when performing action in a BeginUpdate/EndUpdate block which the drag and drop operation uses. When the event is fired with batch action you must validate all appointments. 

    I hope this information helps. Should you have any other questions, I will be glad to assist you.

    Regards,
    Dimitar
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WINFORMS.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  6. Marco
    Marco avatar
    87 posts
    Member since:
    Apr 2011

    Posted 28 Aug 2013 Link to this post

    Hello Dimitar

    Thanks for your explanation.

    Now I understand better how the AppointementChanged work with the batch "option".

    I have modified my Appointment.CollectionChanged Sub to handle the batch. It is not perfect because I have some trouble with Entity Framework (some inner batch event are launched in a add event and it's getting in concurrency exception).

    I fix it in hurry with an huggly try catch. It's working fine in a point of view of functionnal test ! (Just pray that's my user won't have to much imagination).

    I think that's I could make something cleaner if I move my context.SaveChange to another place. (form closing, a timer sub started on appointementchanged, a save button)

    The subject of this thread is fully answered for me.

    Thank you very much

  7. Dimitar
    Admin
    Dimitar avatar
    1411 posts

    Posted 30 Aug 2013 Link to this post

    Hi Marco,

    Thank you for writing back.

    I am glad that my explanations were useful for you and you managed to find solution for your case. 

    Indeed moving the saving logic to a save button for example will be a much better solution than the try catch block. By my opinion a save button or when closing the form is way better place for that logic.

    Please let me know if there is something else I can help you with.

    Regards,
    Dimitar
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WINFORMS.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
Back to Top
UI for WinForms is Visual Studio 2017 Ready