Block Days/Times from being booked

6 posts, 0 answers
  1. Jeremy Murtishaw
    Jeremy Murtishaw avatar
    86 posts
    Member since:
    Apr 2009

    Posted 14 Sep 2009 Link to this post

    Hello,
    Currently I have:

    this.radScheduler.ActiveView.AllowAppointmentMove = true;
    this.radScheduler.ActiveView.AllowAppointmentResize = true;

    However, I don't want to allow users to move an appointment to a date or time in the past.

    For example, there is an appointment for 2pm Tuesday.  I want to prevent/block a user from selecting that appointment and moving/dragging it to 11am that day, OR to a day in the past (like the previous Friday).  Since neither situation makes logical sense.

    Is this possible?

    Thanks
    -Jeremy
  2. Matthew Green
    Matthew Green avatar
    27 posts
    Member since:
    Aug 2009

    Posted 14 Sep 2009 Link to this post

    I dont see why not.

    It should be as simple as extending the Appointment class and overriding the Start and End Times like the following:

            public override DateTime End 
            { 
                get { return base.End; } 
                set
                {
                    bool add = value >= DateTime.Today; 
                    if (ClinicAppointment.TimeTo != value && add) 
                    { 
                        base.End = value; 
                        OnPropertyChanged("End"); 
                    }
                }
            } 

    If you were databinding you could check the OnPropertyChanged event, if the value were in the past then set the value back.

    You could probably make some more creative approaches using some of the events: appointmentSelected, appointmentMouseUp, appointmentMouseDown to see where it was going, but im a bit tired to make a example using those. 

    Hope this helps.

    Best Regards, Matthew
  3. Jeremy Murtishaw
    Jeremy Murtishaw avatar
    86 posts
    Member since:
    Apr 2009

    Posted 14 Sep 2009 Link to this post

    Thanks Matthew.  I was actually hoping to have the scheduler not allow the drop to a date/time in the past.

    I had thought setting each SchedulerCellElement cell to enabled=false would do the trick as the telerik documenatation says this will disable user interaction with the cell.  Unfortunately even though the cells are greyed out, you can still select an appointment and drag and drop it to a past date.

    Is there any property on the scheduler to disallow such actions?

    Thanks!
    -Jeremy
  4. Matthew Green
    Matthew Green avatar
    27 posts
    Member since:
    Aug 2009

    Posted 15 Sep 2009 Link to this post

    Having a quick glance i would say there isnt, but I have only used the callender control for a month or so... so still kicking it around.

    Trying the same thing as yourself with an extension method it is indeed acting as you say:

    1 public static void MoveAppointmentLock(this SchedulerMonthViewElement monthView)  
    2         {  
    3             Telerik.WinControls.RadElementCollection collection =   
    4                 (monthView.Children[1] as MonthViewAreaElement).Children;    
    5  
    6             Collection<MonthCellElement> collectionMonthCellElement = new Collection<MonthCellElement>();  
    7             Collection<AppointmentElement> collectionAppointment = new Collection<AppointmentElement>();  
    8  
    9             foreach (var element in collection)  
    10             {  
    11                 if (element is MonthCellElement)  
    12                 {  
    13                     collectionMonthCellElement.Add(element as MonthCellElement);  
    14                     continue;  
    15                 }  
    16                 if (element is AppointmentElement)  
    17                 {  
    18                     collectionAppointment.Add(element as AppointmentElement);  
    19                     continue;  
    20                 }  
    21             }  
    22  
    23             foreach (var element in collectionMonthCellElement)  
    24             {  
    25                 if (element.Date < DateTime.Today)  
    26                 {  
    27                     element.Enabled = false;  
    28                 }  
    29             }  
    30  
    31             foreach (var element in collectionAppointment)  
    32             {  
    33                 if (element.Start < DateTime.Today)  
    34                 {   
    35                     var appointment = element.Appointment;  
    36                     appointment.AllowEdit = false;  
    37                     element.Enabled = false;  
    38                 }  
    39             }  
    40         } 

    Funny thing is that once a new item is dragged into a disabled cell then all the appointments become active again as well. Achieving this might not be as simple as i thought. There is a couple of Telerik guys who might be able to help (normally around at least every other day).
    If i find anything in the mean time i'll let you know.

    Best Regards,
    Matthew
  5. Matthew Green
    Matthew Green avatar
    27 posts
    Member since:
    Aug 2009

    Posted 15 Sep 2009 Link to this post


    I have a nearly working solution to the dragging of elements in a monthview (doesn't allow the mouse to enter a cell in the past that is carrying a appointment, returning the mouse and its appointment to the cell where the element was previously situated). The below sample isnt perfect but could get you going if there isnt a easier solution.

    //Add the following events   
    this.scheduler.AppointmentMouseDown += new EventHandler<SchedulerAppointmentMouseEventArgs>(scheduler_AppointmentMouseDown);  
    this.scheduler.AppointmentMouseUp += new EventHandler<SchedulerAppointmentMouseEventArgs>(scheduler_AppointmentMouseUp);  
    this.scheduler.MouseMove += new MouseEventHandler(scheduler_MouseMove); 


    void scheduler_MouseMove(object sender, MouseEventArgs e)  
    {  
        //alternatively check mouse down ... though it may be difficult to determine if it is carrying a appointment  
        if (mouseDown)   
        {  
            CheckCells(e);  
        }  
    }  
     
    bool mouseDown;  
    Appointment mouseAppointment;   
    void scheduler_AppointmentMouseDown(object sender, SchedulerAppointmentMouseEventArgs e)  
    {  
        mouseDown = true;  
        mouseAppointment = e.Appointment as Appointment;  
    }  
    void scheduler_AppointmentMouseUp(object sender, SchedulerAppointmentMouseEventArgs e)  
    {  
        mouseDown = false;  
        mouseAppointment = null;  
    }  
     
    void CheckCells(MouseEventArgs ev)   
    {  
        int x, y;  
        x = ev.X;  
        y = ev.Y;  
     
        if (this.scheduler.SchedulerElement.ViewElement is SchedulerMonthViewElement)  
        {  
            SchedulerMonthViewElement monthView = scheduler.SchedulerElement.ViewElement as SchedulerMonthViewElement;  
            MonthViewAreaElement area = monthView.Children[1] as MonthViewAreaElement;  
     
            var monthCells = area.Children.OfType<MonthCellElement>();  
            var allowedDays = monthCells.Where(e => e.Date >= DateTime.Today);  
            var disallowedDays = monthCells.Where(e => e.Date < DateTime.Today).ToArray();  
     
            if (disallowedDays.Length > 0)  
            {  
                foreach (var day in disallowedDays)  
                {  
                    bool withinCellX = x >= day.BoundingRectangle.Location.X && x <= (day.BoundingRectangle.Location.X + day.BoundingRectangle.Width);  
                    bool withinCellY = y >= day.BoundingRectangle.Location.Y && y <= (day.BoundingRectangle.Location.Y + day.BoundingRectangle.Height);  
                    if (withinCellX && withinCellY)  
                    {  
                        var previousCell = from a in allowedDays where a.Date.DayOfYear == mouseAppointment.Start.DayOfYear select a;  
                        var point = previousCell.FirstOrDefault();  
                          
                        //Move mouse out of the disallowed cell  
                        var newPoint =  
                            new System.Drawing.Point(point.BoundingRectangle.Location.X + (point.BoundingRectangle.Width / 2), point.BoundingRectangle.Location.Y + (point.BoundingRectangle.Height / 2));  
                        //Move   
                        Cursor.Position = newPoint;  
                    }  
                }  
            }  
        }  
    The above Cursor.Position will require a different value as i think i have got it wrong there. I had targeted the cell where the appointment originally came from, but testing seems to be giving me a different position. A similar technique to week / day views should give you the functionality you are probably after. The capture area (withinCellX & withinCellY) for past cells is a little off so a little padding may be required.

    You may also want to hide the context menu for cells found in the past, to do this have a look at posts on the 1st sept on this thread http://www.telerik.com/community/forums/winforms/scheduler/custom-appointments-dialog-amp-occurences.aspx 
    just add some logic which checks the date.

    You may also want to display a validation warning or similar to remind the user that the element cannot be moved that way.

    Best Regards,
    Matthew
  6. Boyko Markov
    Admin
    Boyko Markov avatar
    610 posts

    Posted 18 Sep 2009 Link to this post

    Hello Matthew and Jeremy,

    I am very happy about the discussion which you made here guys. It gave me some ideas for new features which we should definitely add in RadScheduler. I am thinking about some new drag/drop events which will help you to easily cancel the drag operation on its starting/ending point and an event which will give you information where the appointment dragging feedback currently is. I'm very sorry that we can not provide this as built-in functionality at the moment which will help you with your scenario. Mathew, your solution seems very interesting. I will give it a try.

    All the best,
    Boyko Markov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Back to Top