I'm having a problem with the ScheduleView.
My GroupHeaders style breaks when i try to add new resources. I think the easiest way to explain the problem is with the attached pictures. But my "outer" group header affects the "inner" group headers height (set to the same as the outer).
This also happens if I try to "reinitialize" the view with the exact same data as I had the first time.
I'm using a GroupHeaderContentTemplateSelector with a custom style.
The following is my view.
<
Window
x:Class
=
"RadScheduleViewBug.MainWindow"
xmlns:ignore
=
"http://www.galasoft.ch/ignore"
mc:Ignorable
=
"d ignore"
xmlns:local
=
"clr-namespace:RadScheduleViewBug"
xmlns:scheduleView
=
"clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.ScheduleView"
Height
=
"500"
Width
=
"500"
Title
=
"MVVM Light Application"
xmlns:telerik
=
"http://schemas.telerik.com/2008/xaml/presentation"
DataContext
=
"{Binding Main, Source={StaticResource Locator}}"
>
<
Window.Resources
>
<
ResourceDictionary
>
<
ResourceDictionary.MergedDictionaries
>
<
ResourceDictionary
Source
=
"Skins/MainSkin.xaml"
/>
</
ResourceDictionary.MergedDictionaries
>
<
DataTemplate
x:Key
=
"HorizontalTemplate"
>
<
TextBlock
Margin
=
"4"
Text
=
"{Binding Name, StringFormat=dd dddd}"
/>
</
DataTemplate
>
<
DataTemplate
x:Key
=
"VerticalTemplate"
>
<
telerik:LayoutTransformControl
>
<
telerik:LayoutTransformControl.LayoutTransform
>
<
RotateTransform
Angle
=
"-90"
/>
</
telerik:LayoutTransformControl.LayoutTransform
>
<
TextBlock
Margin
=
"4"
Text
=
"{Binding Name, StringFormat=dd dddd}"
VerticalAlignment
=
"Top"
ToolTipService.ToolTip
=
"{Binding Name}"
/>
</
telerik:LayoutTransformControl
>
</
DataTemplate
>
<
DataTemplate
x:Key
=
"HorizontalResourceTemplate"
>
<
Border
Margin
=
"3"
Width
=
"100"
MaxHeight
=
"20"
>
<
Border.Background
>
<
SolidColorBrush
Color
=
"White"
></
SolidColorBrush
>
</
Border.Background
>
<
StackPanel
>
<
TextBlock
Margin
=
"5"
FontSize
=
"12"
Text
=
"{Binding Name.DisplayName}"
/>
</
StackPanel
>
</
Border
>
</
DataTemplate
>
<
DataTemplate
x:Key
=
"VerticalResourceTemplate"
>
<
telerik:LayoutTransformControl
Height
=
"93"
>
<
telerik:LayoutTransformControl.LayoutTransform
>
<
RotateTransform
Angle
=
"-90"
/>
</
telerik:LayoutTransformControl.LayoutTransform
>
<
Border
Margin
=
"1,0,3,1"
>
<
StackPanel
>
<
TextBlock
Width
=
"80"
TextTrimming
=
"CharacterEllipsis"
Margin
=
"5"
FontSize
=
"12"
Text
=
"{Binding Name.DisplayName}"
ToolTipService.ToolTip
=
"{Binding Name.DisplayName}"
>
<
TextBlock.Foreground
>
<
SolidColorBrush
Color
=
"Red"
/>
</
TextBlock.Foreground
>
</
TextBlock
>
</
StackPanel
>
</
Border
>
</
telerik:LayoutTransformControl
>
</
DataTemplate
>
<
local:CustomTimeRulerItemStyleSelector
x:Key
=
"CustomTimeRulerItemStyleSelector"
>
<
local:CustomTimeRulerItemStyleSelector.MajorTickLineStyle
>
<
Style
TargetType
=
"scheduleView:TimeRulerLine"
BasedOn
=
"{StaticResource TimeRulerLineStyle}"
>
<
Setter
Property
=
"BorderBrush"
Value
=
"WhiteSmoke"
/>
<
Setter
Property
=
"Background"
Value
=
"White"
/>
<
Setter
Property
=
"Template"
>
<
Setter.Value
>
<
ControlTemplate
TargetType
=
"scheduleView:TimeRulerLine"
>
<
Border
x:Name
=
"LineVisual"
BorderBrush
=
"{TemplateBinding BorderBrush}"
Background
=
"{TemplateBinding Background}"
BorderThickness
=
"1 0 0 0"
/>
</
ControlTemplate
>
</
Setter.Value
>
</
Setter
>
</
Style
>
</
local:CustomTimeRulerItemStyleSelector.MajorTickLineStyle
>
<
local:CustomTimeRulerItemStyleSelector.MinorTickLineStyle
>
<
Style
TargetType
=
"scheduleView:TimeRulerLine"
BasedOn
=
"{StaticResource TimeRulerLineStyle}"
>
<
Setter
Property
=
"BorderBrush"
Value
=
"WhiteSmoke"
/>
<
Setter
Property
=
"Background"
Value
=
"White"
/>
<
Setter
Property
=
"Template"
>
<
Setter.Value
>
<
ControlTemplate
TargetType
=
"scheduleView:TimeRulerLine"
>
<
Border
x:Name
=
"LineVisual"
BorderBrush
=
"{TemplateBinding BorderBrush}"
Background
=
"{TemplateBinding Background}"
BorderThickness
=
"1 0 0 0"
/>
</
ControlTemplate
>
</
Setter.Value
>
</
Setter
>
</
Style
>
</
local:CustomTimeRulerItemStyleSelector.MinorTickLineStyle
>
</
local:CustomTimeRulerItemStyleSelector
>
<
local:CustomGroupHeaderStyleSelector
x:Key
=
"CustomGroupHeaderStyleSelector"
>
<
local:CustomGroupHeaderStyleSelector.CalendarStyle
>
<
Style
TargetType
=
"telerik:GroupHeader"
>
<
Setter
Property
=
"Margin"
Value
=
"0, 0, 0, 15"
/>
<
Setter
Property
=
"BorderThickness"
Value
=
"0, 0, 0, 0"
/>
</
Style
>
</
local:CustomGroupHeaderStyleSelector.CalendarStyle
>
<
local:CustomGroupHeaderStyleSelector.ChildStyle
>
<
Style
TargetType
=
"telerik:GroupHeader"
>
<
Setter
Property
=
"BorderThickness"
Value
=
"0, 0, 0, 0"
/>
<
Setter
Property
=
"BorderBrush"
Value
=
"WhiteSmoke"
/>
</
Style
>
</
local:CustomGroupHeaderStyleSelector.ChildStyle
>
</
local:CustomGroupHeaderStyleSelector
>
<
local:CustomGroupHeaderContentTemplateSelector
x:Key
=
"CustomGroupHeaderContentTemplateSelector"
HorizontalTemplate
=
"{StaticResource HorizontalTemplate}"
VerticalResourceTemplate
=
"{StaticResource VerticalResourceTemplate}"
HorizontalResourceTemplate
=
"{StaticResource HorizontalResourceTemplate}"
VerticalTemplate
=
"{StaticResource VerticalTemplate}"
/>
</
ResourceDictionary
>
</
Window.Resources
>
<
Grid
x:Name
=
"LayoutRoot"
>
<
StackPanel
>
<
telerik:RadButton
Content
=
"Add appointment"
Command
=
"{Binding AddNewAppointment}"
/>
<
telerik:RadButton
Content
=
"Remove appointment"
Command
=
"{Binding RemoveAppointment}"
/>
<
telerik:RadButton
Content
=
"Add measure point"
Command
=
"{Binding AddMeasurePoint}"
/>
<
telerik:RadButton
Content
=
"Remove measure point"
Command
=
"{Binding RemoveMeasurePoint}"
/>
<
telerik:RadButton
Content
=
"Re-initialize"
Command
=
"{Binding Redo}"
/>
<
telerik:RadScheduleView
ScrollViewer.CanContentScroll
=
"True"
Grid.Row
=
"1"
x:Name
=
"Schedule"
AppointmentsSource
=
"{Binding Appointments, Mode=OneWay}"
ResourceTypesSource
=
"{Binding ResourceTypes, Mode=OneWay}"
CategoriesSource
=
"{Binding Categories, Mode=OneWay}"
SelectedAppointment
=
"{Binding SelectedAppointment, Mode=OneWay}"
CurrentDate
=
"{Binding PeriodStart, Mode=OneWay}"
SelectedSlot
=
"{Binding SelectedSlot, Mode=OneWay}"
GroupHeaderContentTemplateSelector
=
"{StaticResource CustomGroupHeaderContentTemplateSelector}"
TimeRulerItemStyleSelector
=
"{StaticResource CustomTimeRulerItemStyleSelector}"
ShowCurrentTimeIndicator
=
"True"
NavigationHeaderVisibility
=
"Collapsed"
SpecialSlotStyleSelector
=
"{StaticResource SpecialSlotStyleSelector}"
SnapAppointments
=
"True"
>
<
telerik:RadScheduleView.DragDropBehavior
>
<
local:CustomDragDropBehaviour
/>
</
telerik:RadScheduleView.DragDropBehavior
>
<
telerik:RadContextMenu.ContextMenu
>
<
telerik:RadContextMenu
x:Name
=
"radContextMenu"
ItemsSource
=
"{Binding ContextMenu}"
/>
</
telerik:RadContextMenu.ContextMenu
>
<
telerik:RadScheduleView.ActiveViewDefinition
>
<
telerik:TimelineViewDefinition
VisibleDays
=
"{Binding Path=DataContext.VisibleDays, ElementName=Schedule, FallbackValue=3}"
MaxTimeRulerExtent
=
"Infinity"
StretchAppointments
=
"False"
TimerulerMajorTickStringFormat
=
"{}{0:H tt}"
TimerulerGroupStringFormat
=
"{}{0:dd-MM}"
/>
</
telerik:RadScheduleView.ActiveViewDefinition
>
<
telerik:RadScheduleView.GroupDescriptionsSource
>
<
telerik:GroupDescriptionCollection
>
<
scheduleView:DateGroupDescription
/>
<
local:RSResourceGroupDescription
ResourceType
=
"Root"
/>
<
local:RSResourceGroupDescription
ResourceType
=
"Child"
/>
</
telerik:GroupDescriptionCollection
>
</
telerik:RadScheduleView.GroupDescriptionsSource
>
</
telerik:RadScheduleView
>
</
StackPanel
>
</
Grid
>
</
Window
>
and the following is my ViewModel
using
GalaSoft.MvvmLight;
using
GalaSoft.MvvmLight.Command;
using
RadScheduleViewBug.Model;
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
Telerik.Windows.Controls.ScheduleView;
using
Telerik.Windows.Controls;
using
System.Windows.Media;
using
System.Collections.ObjectModel;
namespace
RadScheduleViewBug.ViewModel
{
public
class
MainViewModel : GalaSoft.MvvmLight.ViewModelBase
{
int
_newAppId = 0;
int
_newMeasurePointId = 5;
public
RelayCommand AddMeasurePoint {
get
;
set
; }
public
RelayCommand RemoveMeasurePoint {
get
;
set
; }
public
RelayCommand AddNewAppointment {
get
;
set
; }
public
RelayCommand RemoveAppointment {
get
;
set
; }
public
RelayCommand Redo {
get
;
set
; }
public
ObservableCollection<RSIntervalAppointment> Appointments {
get
;
set
; }
public
ObservableCollection<ResourceType> ResourceTypes {
get
;
set
; }
public
RSIntervalAppointment SelectedAppointment {
get
;
set
; }
public
Telerik.Windows.Controls.ScheduleView.Slot SelectedSlot {
get
;
set
; }
public
DateTime PeriodStart {
get
;
set
; }
public
DateTime IntervalEnd {
get
;
set
; }
public
int
VisibleDays {
get
;
set
; } = 4;
ResourceType rootResourceType;
ResourceType childResourceType;
Category scheduleCategory =
new
Category(
"Schedule"
,
new
SolidColorBrush(Colors.Red));
Category shiftCategory =
new
Category(
"Shift"
,
new
SolidColorBrush(Colors.Green));
Category breakCategory =
new
Category(
"Break"
,
new
SolidColorBrush(Colors.Blue));
public
MainViewModel()
{
InitializeAction();
AddNewAppointment =
new
RelayCommand(AddNewAppointmentAction);
RemoveMeasurePoint =
new
RelayCommand(RemoveMeasurePointAction);
AddMeasurePoint =
new
RelayCommand(AddMeasurePointAction);
RemoveAppointment =
new
RelayCommand(RemoveAppointmentAction);
Redo =
new
RelayCommand(InitializeAction);
}
public
void
AddNewAppointmentAction()
{
_newAppId++;
//New Appointment
var app =
new
RSIntervalAppointment(
new
ProxyItem() { IntervalStart = DateTime.Now.AddHours(_newAppId).AddMinutes(1), IntervalEnd = DateTime.Now.AddHours(_newAppId + 1).AddMinutes(-1), Name = _newAppId.ToString() });
app.Resources.Add(childResourceType.Resources.Last());
app.Resources.Add(rootResourceType.Resources.Last());
app.Category = shiftCategory;
Appointments.Add(app);
}
private
void
RemoveAppointmentAction()
{
if
(Appointments.Count > 0)
Appointments.Remove(Appointments.Last());
}
private
void
AddMeasurePointAction()
{
_newMeasurePointId++;
var resource =
new
RSReportItemResource(
new
ReportItem() { Name = _newMeasurePointId.ToString() },
"Measure p "
+ _newMeasurePointId.ToString());
rootResourceType.Resources.Add(resource);
//Refresh view
ResourceTypes.Remove(childResourceType);
ResourceTypes.Add(childResourceType);
}
private
void
RemoveMeasurePointAction()
{
if
(rootResourceType.Resources.Count > 1)
{
rootResourceType.Resources.Remove(rootResourceType.Resources.Last());
//Refresh view
ResourceTypes.Remove(rootResourceType);
ResourceTypes.Add(rootResourceType);
}
}
public
void
InitializeAction()
{
ResourceTypes =
new
ObservableCollection<ResourceType>();
rootResourceType =
new
ResourceType(
"Root"
);
childResourceType =
new
ResourceType(
"Child"
);
ResourceTypes.Add(rootResourceType);
ResourceTypes.Add(childResourceType);
var measurePoint1 =
new
RSReportItemResource(
new
ReportItem() { Name =
"1"
},
"Measure point 1"
);
rootResourceType.Resources.Add(measurePoint1);
var measurePoint2 =
new
RSReportItemResource(
new
ReportItem() { Name =
"1"
},
"Measure point 2"
);
rootResourceType.Resources.Add(measurePoint2);
var schedule =
new
RSEntityTypeResource(
new
ProxyItem(),
"Schedule"
);
childResourceType.Resources.Add(schedule);
var breaks =
new
RSEntityTypeResource(
new
ProxyItem(),
"Breaks"
);
childResourceType.Resources.Add(breaks);
var shift =
new
RSEntityTypeResource(
new
ProxyItem(),
"Shift"
);
childResourceType.Resources.Add(shift);
PeriodStart = DateTime.Now.AddDays(-1);
Appointments =
new
ObservableCollection<RSIntervalAppointment>();
for
(var i = 0; i < 10; i++)
{
var app =
new
RSIntervalAppointment(
new
ProxyItem() { IntervalStart = DateTime.Now.AddHours(-i), IntervalEnd = DateTime.Now.AddHours(-i + 1), Name = i.ToString() });
app.Resources.Add(childResourceType.Resources[0]);
app.Resources.Add(rootResourceType.Resources[0]);
app.Category = scheduleCategory;
Appointments.Add(app);
}
for
(var i = 0; i < 10; i++)
{
var app =
new
RSIntervalAppointment(
new
ProxyItem() { IntervalStart = DateTime.Now.AddHours(-i), IntervalEnd = DateTime.Now.AddHours(-i + 1), Name = i.ToString() });
app.Resources.Add(childResourceType.Resources[2]);
app.Resources.Add(rootResourceType.Resources[0]);
app.Category = shiftCategory;
Appointments.Add(app);
}
RaisePropertyChanged(() => ResourceTypes);
RaisePropertyChanged(() => Appointments);
}
}
}
This all the code needed to recreate the problem in a MvvmLight project.
You can clearly see the error in the attached files.
I have also made a project with a recreation of the problem that I can send you if that would help you in assisting me.