Hi,
I'm trying to migrate from RadScheduler to RadscheduleView and I am on version 2012.1.326.40 right now.
Since all my appointments are AllDayEvents, I need the week and day view to only show the AllDayArea and also the AllDayArea needs to have a vertical scrollbar.
I achieved this with the RadScheduler by using a custom theme, reflections-hacks, runtime manipulation of the visual tree and inheriting/reimplementing some AppointmentPanels.
How can I achieve this with RadScheduleView? I hope there is an easier way now.
Any help would be highly appreciated.
Best Regards
Steffen
6 Answers, 1 is accepted
Hello Steffen,
Thank you for the shared information.
I am afraid that the desired requirement it not supported by the RadScheduleView. Currently the all day area part is inside the panel that hosts the rest of the appointments and there isn't an option to show only the all day area.
That said, we do have a feature request logged in our feedback portal to introduce the option for scrolling inside it: ScheduleView: Allow scrolling of the all day area.
I hope you find this information helpful.
Regards,
Vladimir Stoyanov
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.
Hello Vladimir,
thank's for the feedback.
I got it working by manipulating the visual tree at runtime. So now I got only the all day area and a vertical scrollbar.
The problem I am facing now is that the day-template has dynamic height because of vertical expanders.
So setting MinAppointmentHeight is not possible because it is dynamic and can differ for every appointment that day. With RadScheduler I just called InvalidateVisual on the AppointmentPanel whenever the state of an expander changed. Can you suggest how I can implement this behaviour with RadScheduleView? I understand that this is not officially supported - it just has to work, so we can finally upgrage from 2012.1.
Best Regards
Steffen
Hello Steffen,
Thank you for the update.
While it is difficult to suggest a concrete approach without being able to test the exact scenario on my end, if setting a different minimum/maximum height for the appointments would be helpful, you can consider creating a custom AppointmentStyleSelector and providing different styles for the appointments (setting their MinHeight/MaxHeight).
Alternatively, you can also try locating the AppointmentsPanel element within the RadScheduleView with the ChildrenOfType extension method and forcing it to be remeasured.
I hope this helps.
Regards,
Vladimir Stoyanov
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.
Hello Vladimir,
I prepared a sample project to demonstrate the current behaviour and the desired behaviour.
In the first tab you see RadScheduleView in scrollable AllDayView and Appointments with expanders (which don't really work, because it seems appointment-height is fixed to RadScheduleView's MinAppointmentHeight).
The second Tab shows the desired behaviour (our application currently has with old RadScheduler) by using an ItemsControl.
Any help would be highly appreciated.
.cs:
namespace
ScheduleViewDemo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public
partial
class
MainWindow : Window
{
public
MainWindow()
{
InitializeComponent();
radScheduler.AppointmentItemContentTemplateSelector =
new
TourTemplateSelector(radScheduler, FindResource(
"DayAppointmentTemplate"
)
as
DataTemplate, FindResource(
"WeekTemplateFixedHeights"
)
as
DataTemplate, FindResource(
"MonthAppointmentTemplate"
)
as
DataTemplate);
DateTime today = DateTime.Now;
List<Appointment> appointments =
new
List<Appointment>();
appointments.Add(
new
Appointment() { IsAllDayEvent =
true
, Start = today.Date, End = today.Date.AddHours(14), Subject =
"Test 1"
});
appointments.Add(
new
Appointment() { IsAllDayEvent =
true
, Start = today.Date, End = today.Date.AddHours(14), Subject =
"Test 2"
});
appointments.Add(
new
Appointment() { IsAllDayEvent =
true
, Start = today.Date, End = today.Date.AddHours(14), Subject =
"Test 3"
});
appointments.Add(
new
Appointment() { IsAllDayEvent =
true
, Start = today.Date, End = today.Date.AddHours(14), Subject =
"Test 4"
});
appointments.Add(
new
Appointment() { IsAllDayEvent =
true
, Start = today.Date, End = today.Date.AddHours(14), Subject =
"Test 5"
});
appointments.Add(
new
Appointment() { IsAllDayEvent =
true
, Start = today.Date, End = today.Date.AddHours(14), Subject =
"Test 6"
});
appointments.Add(
new
Appointment() { IsAllDayEvent =
true
, Start = today.Date, End = today.Date.AddHours(14), Subject =
"Test 7"
});
appointments.Add(
new
Appointment() { IsAllDayEvent =
true
, Start = today.Date, End = today.Date.AddHours(14), Subject =
"Test 8"
});
appointments.Add(
new
Appointment() { IsAllDayEvent =
true
, Start = today.Date, End = today.Date.AddHours(14), Subject =
"Test 9"
});
appointments.Add(
new
Appointment() { IsAllDayEvent =
true
, Start = today.Date, End = today.Date.AddHours(14), Subject =
"Test 10"
});
appointments.Add(
new
Appointment() { IsAllDayEvent =
true
, Start = today.Date, End = today.Date.AddHours(14), Subject =
"Test 11"
});
appointments.Add(
new
Appointment() { IsAllDayEvent =
true
, Start = today.Date, End = today.Date.AddHours(14), Subject =
"Test 12"
});
appointments.Add(
new
Appointment() { IsAllDayEvent =
true
, Start = today.Date, End = today.Date.AddHours(14), Subject =
"Test 13"
});
appointments.Add(
new
Appointment() { IsAllDayEvent =
true
, Start = today.Date, End = today.Date.AddHours(14), Subject =
"Test 14"
});
radScheduler.AppointmentsSource = appointments;
ic_dayBehaviour.ItemsSource = appointments;
}
private
void
radScheduler_Loaded(
object
sender, RoutedEventArgs e)
{
if
(!radScheduler.IsLoaded)
{
return
;
}
manageAllDayAreaAndScrollViewer();
}
private
void
manageAllDayAreaAndScrollViewer()
{
if
(radScheduler.ActiveViewDefinitionIndex == 1)
//week
{
var tmp = radScheduler.ChildrenOfType<AppointmentsPanel>();
if
(tmp.Count() > 0)
{
var p = tmp.ElementAt(0);
if
(!(p.Parent
is
Grid))
{
return
;
}
var parent = (Grid)p.Parent;
parent.Children.Remove(p);
var s =
new
ScrollViewer() { VerticalScrollBarVisibility = ScrollBarVisibility.Visible };
s.VerticalAlignment = VerticalAlignment.Top;
Grid.SetColumnSpan(s, 2);
Grid.SetColumn(s, 0);
Binding b1 =
new
Binding() { Path =
new
PropertyPath(
"ActualHeight"
), RelativeSource =
new
RelativeSource(RelativeSourceMode.FindAncestor) { AncestorType =
typeof
(RadTransitionControl) } };
s.SetBinding(FrameworkElement.HeightProperty, b1);
s.Content = p;
parent.Children.Add(s);
}
foreach
(var b
in
radScheduler.ChildrenOfType<Border>())
{
if
(b.Name ==
"HorizontalHeadersBorder"
)
{
b.MinHeight = 10000;
Grid.SetColumnSpan(b, 2);
Grid.SetColumn(b, 0);
break
;
}
}
}
else
if
(radScheduler.ActiveViewDefinitionIndex == 2)
//day (currently same as week)
{
var tmp = radScheduler.ChildrenOfType<AppointmentsPanel>();
if
(tmp.Count() > 0)
{
var p = tmp.ElementAt(0);
if
(!(p.Parent
is
Grid))
{
return
;
}
var parent = (Grid)p.Parent;
parent.Children.Remove(p);
var s =
new
ScrollViewer() { VerticalScrollBarVisibility = ScrollBarVisibility.Visible };
s.VerticalAlignment = VerticalAlignment.Top;
Grid.SetColumnSpan(s, 2);
Grid.SetColumn(s, 0);
Binding b1 =
new
Binding() { Path =
new
PropertyPath(
"ActualHeight"
), RelativeSource =
new
RelativeSource(RelativeSourceMode.FindAncestor) { AncestorType =
typeof
(RadTransitionControl) } };
s.SetBinding(FrameworkElement.HeightProperty, b1);
s.Content = p;
parent.Children.Add(s);
}
foreach
(var b
in
radScheduler.ChildrenOfType<Border>())
{
if
(b.Name ==
"HorizontalHeadersBorder"
)
{
b.MinHeight = 10000;
Grid.SetColumnSpan(b, 2);
Grid.SetColumn(b, 0);
break
;
}
}
}
else
//month view must be all standard
{
var tmp = radScheduler.ChildrenOfType<AppointmentsPanel>();
if
(tmp.Count() > 0)
{
var p = tmp.ElementAt(0);
if
(!(p.Parent
is
ScrollViewer))
{
return
;
}
var parent = (ScrollViewer)p.Parent;
var grandParent = (Grid)parent.Parent;
parent.Content =
null
;
grandParent.Children.Remove(parent);
grandParent.Children.Add(p);
}
foreach
(var b
in
radScheduler.ChildrenOfType<Border>())
{
if
(b.Name ==
"HorizontalHeadersBorder"
)
{
b.MinHeight = 0;
Grid.SetColumnSpan(b, 1);
Grid.SetColumn(b, 1);
break
;
}
}
}
}
private
void
radScheduler_ActiveViewDefinitionChanged(
object
sender, EventArgs e)
{
if
(radScheduler.ActiveViewDefinitionIndex == 0)
{
radScheduler.MinAppointmentHeight = 50d;
}
else
if
(radScheduler.ActiveViewDefinitionIndex == 1)
{
radScheduler.MinAppointmentHeight = 150d;
}
else
if
(radScheduler.ActiveViewDefinitionIndex == 2)
{
radScheduler.MinAppointmentHeight = 150d;
//??? shoud be dynamic
}
manageAllDayAreaAndScrollViewer();
}
private
void
radScheduler_ShowDialog(
object
sender, ShowDialogEventArgs e)
{
e.Cancel =
true
;
}
private
void
Expander_Expanded(
object
sender, RoutedEventArgs e)
{
var p = ((FrameworkElement)sender).ParentOfType<AppointmentsPanel>();
if
(p !=
null
)
{
p.InvalidateVisual();
}
}
}
//class
public
class
TourTemplateSelector : ScheduleViewDataTemplateSelector
{
private
DataTemplate m_dayAppointmentTemplate =
null
;
private
DataTemplate m_weekAppointmentTemplate =
null
;
private
DataTemplate m_monthAppointmentTemplate =
null
;
private
readonly
RadScheduleView m_parent;
public
TourTemplateSelector(RadScheduleView radScheduler, DataTemplate dayAppointmentTemplate, DataTemplate weekAppointmentTemplate, DataTemplate monthAppointmentTemplate)
{
m_parent = radScheduler;
m_dayAppointmentTemplate = dayAppointmentTemplate;
m_weekAppointmentTemplate = weekAppointmentTemplate;
m_monthAppointmentTemplate = monthAppointmentTemplate;
}
public
override
DataTemplate SelectTemplate(
object
item, DependencyObject container, ViewDefinitionBase activeViewDeifinition)
{
if
(m_parent.ActiveViewDefinitionIndex == 2)
{
return
m_dayAppointmentTemplate;
}
else
if
(m_parent.ActiveViewDefinitionIndex == 0)
{
return
m_monthAppointmentTemplate;
}
return
m_weekAppointmentTemplate;
}
}
//class
}
//namespace
.xaml:
<
Window
x:Class
=
"ScheduleViewDemo.MainWindow"
xmlns:telerik
=
"http://schemas.telerik.com/2008/xaml/presentation"
Title
=
"MainWindow"
WindowState
=
"Maximized"
>
<
Window.Resources
>
<
DataTemplate
x:Key
=
"DayAppointmentTemplate"
>
<
Border
BorderThickness
=
"2"
BorderBrush
=
"Black"
>
<
StackPanel
Orientation
=
"Vertical"
>
<
Expander
Header
=
"UP"
Background
=
"Orange"
IsExpanded
=
"True"
ExpandDirection
=
"Up"
Expanded
=
"Expander_Expanded"
Collapsed
=
"Expander_Expanded"
>
<
Label
MinHeight
=
"100"
MaxHeight
=
"100"
Background
=
"Orange"
Content
=
"{Binding Path=Subject}"
/>
</
Expander
>
<
Expander
Header
=
"DOWN"
Background
=
"Lavender"
IsExpanded
=
"False"
ExpandDirection
=
"Down"
Expanded
=
"Expander_Expanded"
Collapsed
=
"Expander_Expanded"
>
<
Label
MinHeight
=
"100"
MaxHeight
=
"100"
Background
=
"Lavender"
Content
=
"{Binding Path=Subject}"
/>
</
Expander
>
</
StackPanel
>
</
Border
>
</
DataTemplate
>
<
DataTemplate
x:Key
=
"WeekTemplateFixedHeights"
>
<
Label
Content
=
"{Binding Path=Subject}"
MinHeight
=
"150"
MaxHeight
=
"150"
Height
=
"150"
Background
=
"Yellow"
/>
</
DataTemplate
>
<
DataTemplate
x:Key
=
"MonthAppointmentTemplate"
>
<
Label
Content
=
"{Binding Path=Subject}"
Background
=
"Green"
MinHeight
=
"50"
MaxHeight
=
"50"
Height
=
"50"
/>
</
DataTemplate
>
</
Window.Resources
>
<
TabControl
>
<
TabItem
Header
=
"RadScheduleView"
>
<
telerik:RadScheduleView
Name
=
"radScheduler"
Loaded
=
"radScheduler_Loaded"
VisibleRangeChanged
=
"radScheduler_ActiveViewDefinitionChanged"
ShowDialog
=
"radScheduler_ShowDialog"
ActiveViewDefinitionIndex
=
"2"
MinAppointmentHeight
=
"150"
>
<
telerik:RadScheduleView.ViewDefinitions
>
<
telerik:MonthViewDefinition
/>
<
telerik:WeekViewDefinition
ShowAllDayArea
=
"True"
EnableSmallAppointmentRendering
=
"True"
/>
<
telerik:DayViewDefinition
ShowAllDayArea
=
"True"
EnableSmallAppointmentRendering
=
"True"
/>
</
telerik:RadScheduleView.ViewDefinitions
>
</
telerik:RadScheduleView
>
</
TabItem
>
<
TabItem
Header
=
"Desired Behaviour DayView"
>
<
ScrollViewer
VerticalScrollBarVisibility
=
"Visible"
>
<
ItemsControl
Name
=
"ic_dayBehaviour"
ItemTemplate
=
"{StaticResource DayAppointmentTemplate}"
>
</
ItemsControl
>
</
ScrollViewer
>
</
TabItem
>
</
TabControl
>
</
Window
>
Best Regards
Steffen
Hello Steffen,
Thank you for the shared code snippets.
I checked out the scenario on my end, however I am afraid that I was not able to come up with a viable approach for achieving the desired look. Simply placing the AppointmentsPanel inside a ScrollViewer is not enough, since the AppointmentsPanel holds the GroupHeader (as well as the AppointmentItem elements) and the GroupHeader will stretch the ScrollViewer. Moreover the AppoinmentsPanel has specific logic inside its measure/arrange methods, which cannot be changed from the outside.
With this in mind, I can only suggest upgrading to our latest version to take advantage of the Agenda View, since it seems closer to what you are trying to achieve visually. That said, note that the different size for the appointments is also unsupported. Please, excuse me for misleading you on that in my previous reply. You can refer to the following feedback item: ScheduleView: Provide a way to have appointments with different width/height set in Day/Week/TimelineViewDefinitions. Currently, it is only possible to set a custom size for the appointments inside the month view.
Regards,
Vladimir Stoyanov
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.
Hello Vladimir,
thanks for the feedback. We came to the same conclusion and cancelled the migration project. Right now we are developing our own scheduler from scratch to fit our needs. After a week it's already 80% done, so this is the way to go instead of "torturing" RadScheduleView. Also we can use our 'fast arrange'-algorithm with the new control, that we developed for RadScheduler. (subclassed the AppointmentPanel and overriden maesure/arrange).
We will still use RadScheduleView for the 'normal' Outlook-Style calender in our application, but this migration has already been done.
Thank you for the great support!
Best Regards
Steffen