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

Probably really simple prob, problem with dragging appointments between groups

1 Answer 96 Views
ScheduleView
This is a migrated thread and some comments may be shown as answers.
Daniel
Top achievements
Rank 1
Daniel asked on 21 Oct 2011, 02:57 PM
Right, I have a list box to the left, and a schedule view to the right. On the schedule view I have included resources, by which I group. When I drag from the list to the schedule view, I can only drop onto the first group. When I attempt to drag an appointment already on the schedule view to another group on the schedule view, it won't allow it.

I have implemented a custom drag drop behaviour class:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.DragDrop;
using Telerik.Windows.Controls.ScheduleView;
 
namespace WpfApplication3
{
	public class ListBoxDragDropBehavior : Freezable
	{
		public static readonly DependencyProperty AppointmentTemplateProperty =
			DependencyProperty.Register("AppointmentTemplate"typeof(DataTemplate), typeof(ListBoxDragDropBehavior), null);
 
		public static readonly DependencyProperty EffectivePixelLengthProperty =
			DependencyProperty.Register("EffectivePixelLength"typeof(TimeSpan), typeof(ListBoxDragDropBehavior), null);
 
		public static readonly DependencyProperty EffectiveOrientationProperty =
			DependencyProperty.Register("EffectiveOrientation"typeof(Orientation), typeof(ListBoxDragDropBehavior), null);
 
		public static readonly DependencyProperty BehaviorProperty =
			DependencyProperty.RegisterAttached("Behavior"typeof(ListBoxDragDropBehavior), typeof(ListBoxDragDropBehavior), new PropertyMetadata(new PropertyChangedCallback(OnBehaviorChanged)));
 
		public DataTemplate AppointmentTemplate
		{
			get { return (DataTemplate)GetValue(AppointmentTemplateProperty); }
			set { SetValue(AppointmentTemplateProperty, value); }
		}
 
		public TimeSpan EffectivePixelLength
		{
			get { return (TimeSpan)GetValue(EffectivePixelLengthProperty); }
			set { SetValue(EffectivePixelLengthProperty, value); }
		}
 
		public Orientation EffectiveOrientation
		{
			get { return (Orientation)GetValue(EffectiveOrientationProperty); }
			set { SetValue(EffectiveOrientationProperty, value); }
		}
        
		public static ListBoxDragDropBehavior GetBehavior(DependencyObject obj)
		{
			return (ListBoxDragDropBehavior)obj.GetValue(BehaviorProperty);
		}
 
		public static void SetBehavior(DependencyObject obj, ListBoxDragDropBehavior value)
		{
			obj.SetValue(BehaviorProperty, value);
		}
 
		protected override Freezable CreateInstanceCore()
		{
			return new ListBoxDragDropBehavior();
		}
 
		private static void OnBehaviorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			System.Windows.Controls.ListBox listBox = d as System.Windows.Controls.ListBox;
			if (listBox == null)
			{
				return;
			}
 
			ListBoxDragDropBehavior behavior = (ListBoxDragDropBehavior)e.OldValue;
			if (behavior != null)
			{
				RadDragAndDropManager.RemoveDragQueryHandler(listBox, new EventHandler<DragDropQueryEventArgs>(behavior.OnDragQuery));
				RadDragAndDropManager.RemoveDropQueryHandler(listBox, new EventHandler<DragDropQueryEventArgs>(behavior.OnDropQuery));
				RadDragAndDropManager.RemoveDropInfoHandler(listBox, new EventHandler<DragDropEventArgs>(behavior.OnDropInfo));
			}
 
			behavior = (ListBoxDragDropBehavior)e.NewValue;
			if (behavior != null)
			{
				RadDragAndDropManager.SetAllowDrop(listBox, true);
				RadDragAndDropManager.AddDragQueryHandler(listBox, new EventHandler<DragDropQueryEventArgs>(behavior.OnDragQuery));
				RadDragAndDropManager.AddDropQueryHandler(listBox, new EventHandler<DragDropQueryEventArgs>(behavior.OnDropQuery));
				RadDragAndDropManager.AddDropInfoHandler(listBox, new EventHandler<DragDropEventArgs>(behavior.OnDropInfo));
			}
		}
 
		private void OnDragQuery(object sender, DragDropQueryEventArgs e)
		{
			if (e.Options.Status == DragStatus.DragQuery)
			{
				System.Windows.Controls.ListBox listbox = sender as System.Windows.Controls.ListBox;
 
				IList<IOccurrence> appointments = listbox.SelectedItems.OfType<IOccurrence>().ToList();
 
				if (appointments.Count == 0)
				{
					return;
				}
 
				e.Options.DragCue = this.CreateDragCue(appointments);
				e.Options.Payload = new ScheduleViewDragDropPayload(listbox.ItemsSource, appointments);
			}
 
			e.QueryResult = true;
		}
 
		private void OnDropQuery(object sender, DragDropQueryEventArgs e)
		{
			e.QueryResult = e.Options.Payload is ScheduleViewDragDropPayload;
		}
 
		private void OnDropInfo(object sender, DragDropEventArgs e)
		{
            System.Windows.Controls.ListBox listBox = sender as System.Windows.Controls.ListBox;
 
			if (e.Options.Status == DragStatus.DropPossible)
			{
				RadDragAndDropManager.Options.Effects = DragDropEffects.All;
				RadDragAndDropManager.Options.CurrentCursor = System.Windows.Input.Cursors.Arrow;
			}
 
            //If the user has dropped - and the drag was made FROM the scheduleview TO the listbox
			if (e.Options.Status == DragStatus.DropComplete && !listBox.IsAncestorOf(e.Options.Source))
			{
				ScheduleViewDragDropPayload payload = e.Options.Payload as ScheduleViewDragDropPayload;
				if (payload != null)
				{
					(payload.SourceAppointmentsSource as IList).RemoveAll((object i) => payload.DraggedAppointments.OfType<object>().Contains(i));
					(listBox.ItemsSource as IList).AddRange(payload.DraggedAppointments);
				}
			}
		}
 
		private ContentControl CreateDragCue(IEnumerable<IOccurrence> appointments)
		{
			bool isHorizontal = this.EffectiveOrientation == Orientation.Horizontal;
			double ticksPerPixel = this.EffectivePixelLength.Ticks;
 
			StackPanel panel = new StackPanel();
			panel.Orientation = this.EffectiveOrientation;
			panel.Background = new SolidColorBrush() { Color = Colors.Transparent };
 
			foreach (IOccurrence appointment in appointments)
			{
				double lenght = appointment.Duration().Ticks / ticksPerPixel;
 
				AppointmentCueItem item = new AppointmentCueItem();
				item.HorizontalContentAlignment = HorizontalAlignment.Stretch;
				item.VerticalContentAlignment = VerticalAlignment.Stretch;
				item.Height = isHorizontal ? 110 : lenght;
				item.Width = isHorizontal ? lenght : 110;
				item.Content = appointment;
				item.ContentTemplate = this.AppointmentTemplate;
 
				panel.Children.Add(item);
			}
 
			ContentControl cue = new ContentControl();
			cue.Content = panel;
 
			return cue;
		}
	}
}

And I have the following xaml definitions for the listbox and schedule view:

        <telerik:RadScheduleView Name="radScheduleView1"
                                 EditAppointmentDialogStyle="{StaticResource EditAppointmentDialogStyle}"
                                 Grid.Column="1"
                                 AppointmentItemContentTemplate="{StaticResource AppointmentItemContentTemplate}"
                                 GroupHeaderContentTemplateSelector="{StaticResource GroupHeaderContentTemplateSelector}">
            <telerik:RadScheduleView.ViewDefinitions>
                <my:DayViewDefinition />
                <my:WeekViewDefinition />
                <my:MonthViewDefinition />
                <my:TimelineViewDefinition />
            </telerik:RadScheduleView.ViewDefinitions>
 
            <scheduleView:RadScheduleView.GroupDescriptionsSource>
                <scheduleView:GroupDescriptionCollection>
                    <scheduleView:ResourceGroupDescription ResourceType="Operatives" />
                </scheduleView:GroupDescriptionCollection>
            </scheduleView:RadScheduleView.GroupDescriptionsSource>
 
        </telerik:RadScheduleView>
 
        <ListBox AllowDrop="True" ItemsSource="{Binding}" Name="listBox1"
                 ItemContainerStyle="{StaticResource ListBoxItemContainerStyle}"
                 ItemTemplate="{StaticResource ListBoxItemTemplate}" SelectionMode="Extended"
                 HorizontalAlignment="Left" Width="270">
            <local:ListBoxDragDropBehavior.Behavior>
                <local:ListBoxDragDropBehavior EffectivePixelLength="{Binding EffectivePixelLength, ElementName=radScheduleView1}"
                                               EffectiveOrientation="{Binding EffectiveOrientation, ElementName=radScheduleView1}"
                                               AppointmentTemplate="{Binding DragVisualCueItemTemplate, ElementName=radScheduleView1}" />
            </local:ListBoxDragDropBehavior.Behavior>
            <ListBox.Background>
                <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
                    <GradientStop Color="#FF4B4B4B" Offset="1" />
                    <GradientStop Color="#FF6E6E6E" />
                </LinearGradientBrush>
            </ListBox.Background>
        </ListBox>

I could really do with cracking this problem ASAP as I have deadlines to meet very soon, I really really appreciate any help you can give.

Thanks,

Dan

1 Answer, 1 is accepted

Sort by
0
Valeri Hristov
Telerik team
answered on 25 Oct 2011, 11:42 AM
Hello Daniel,

I have a simple application that demonstrates a new functionality that allows you to easily create drag-drop between RadScheduleView and ListBox (and other controls if you need). Please, find it attached.

Kind regards,
Valeri Hristov
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

Tags
ScheduleView
Asked by
Daniel
Top achievements
Rank 1
Answers by
Valeri Hristov
Telerik team
Share this question
or