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

Adding resources breaks the height of the GroupHeader

1 Answer 63 Views
ScheduleView
This is a migrated thread and some comments may be shown as answers.
Mattias
Top achievements
Rank 1
Mattias asked on 07 Mar 2017, 05:35 PM

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"
        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. 

1 Answer, 1 is accepted

Sort by
0
Dilyan Traykov
Telerik team
answered on 10 Mar 2017, 09:28 AM
Hello Mattias,

In order to resolve this issue, you can define the AddMeasurePointAction method like so:

private void AddMeasurePointAction()
{
    _newMeasurePointId++;
 
    var resource = new RSReportItemResource(new ReportItem() { Name = _newMeasurePointId.ToString() }, "Measure p " + _newMeasurePointId.ToString());
    rootResourceType.Resources.Add(resource);
 
    //Refresh view
    var resourceTypesTemp = new ObservableCollection<ResourceType>(ResourceTypes);
    ResourceTypes = null;
    ResourceTypes = resourceTypesTemp;
    this.RaisePropertyChanged("ResourceTypes");
}

Please let me know if this works for you.

Regards,
Dilyan Traykov
Telerik by Progress
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which you to write beautiful native mobile apps using a single shared C# codebase.
Tags
ScheduleView
Asked by
Mattias
Top achievements
Rank 1
Answers by
Dilyan Traykov
Telerik team
Share this question
or