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

RadScheduleView - different appointment types

3 Answers 153 Views
ScheduleView
This is a migrated thread and some comments may be shown as answers.
Roland
Top achievements
Rank 1
Roland asked on 07 Mar 2018, 12:53 PM

Hello,

I'm working on a scenario where i have to use 2 different types of appointments, with different properties. both share a common abstract base class, which is derived from the Appointment Class.

public abstract class MyBaseClass : Appointment
{
    private string _designation;
 
    public string Designation
    {
        get { return this.Storage<MyBaseClass>()._designation; }
        set
        {
            var storage = this.Storage<MyBaseClass>();
            if (value == storage._designation) return;
            storage._designation = value;
            this.OnPropertyChanged(() => this.Designation);
        }
    }
}
 
public class DerivedType : MyBaseClass
{
    private string _longText;
 
    public string LongText
    {
        get { return this.Storage<DerivedType>()._longText; }
        set
        {
           var storage = this.Storage<DerivedType>();
            if (value == storage._longText) return;
            storage._longText = value;
            this.OnPropertyChanged(() => this.LongText);
        }
    }
}
 
public class OtherType : MyBaseClass
{
    private bool _myBool;
 
    public bool MyBool
    {
        get { return this.Storage<OtherType>()._myBool; }
        set
        {
            var storage = this.Storage<OtherType>();
            if (value == storage._myBool) return;
            storage._myBool = value;
            this.OnPropertyChanged(() => this.MyBool);
        }
    }
}

 

When using a ListBox, i would simply put multiple datatemplates with DataType={x:Type ...} into the listbox resources. As this did not work, I tried to override  ScheduleViewDataTemplateSelector:

public override DataTemplate SelectTemplate(object item, DependencyObject container, ViewDefinitionBase activeViewDefinition)
{
     Occurrence o = (item as Occurrence);
     if (o.Appointment is DerivedType)
     return this.DerivedTypeTemplate;
...
}

 

<local:TelerikScheduleTemplateSelector x:Key="ScheduleTemplateSelector">
    <local:TelerikScheduleTemplateSelector.DerivedTypeTemplate>
        <DataTemplate>
            <Grid Background="LightGray">
                <Grid.RowDefinitions>
                    <RowDefinition MinHeight="15"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <Label Grid.Row="0" Content="{Binding Appointment.LongText}" />
                <Label Grid.Row="1" MinHeight="30" Margin="2"  Background="Green" />
            </Grid>
        </DataTemplate>
 
        <local:TelerikScheduleTemplateSelector.OtherTypeTemplate>
            <DataTemplate>
                <Grid Background="LightGoldenrodYellow">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="20"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <CheckBox Grid.Row="0" Margin="2" IsChecked="{Binding Appointment.MyBool}" Content="asdf" />
                </Grid>
            </DataTemplate>
        </local:TelerikScheduleTemplateSelector.OtherTypeTemplate>
</local:TelerikScheduleTemplateSelector>

 

this seems to work partially, but I found some problems:

-> the bindings are not recognized, as I cannot set the DataType to DerivedType or to OtherType 
-> Sometimes when switching to other weeks in the scheduleview, I get Binding Errors, because of a missing MyBool Property on DerivedType, and vice-versa

Is there an easier way to get different looks based on the type of the appointment? Could you point me in the right direction, or maybe provide a small sample?

Thanks a lot!

                         

 

 

3 Answers, 1 is accepted

Sort by
0
Martin Ivanov
Telerik team
answered on 08 Mar 2018, 11:23 AM
Hello Roland,

I am not sure that I understand the reported issues. The DataType of the template is not required - the bindings will work also without it. Also, if the template selector returns the correct DateTemplate for the corresponding class there shouldn't be binding errors. I prepared a small example based on your code. Can you give it  a try and let me know if I am missing something?

Regards,
Martin Ivanov
Progress Telerik
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 allow you to write beautiful native mobile apps using a single shared C# codebase.
0
Roland
Top achievements
Rank 1
answered on 08 Mar 2018, 01:10 PM

Hello Martin,

thanks for the fast reply. I tested your sample, but as soon as I add more Items to the ObservableCollection on different days I still get the same problems:

var source = new ObservableCollection<MyBaseClass>()
{
     new DerivedType() { Start = date, End = date.AddHours(2), LongText = "Some looooooooooooooooooong text here" },
     new OtherType() { Start = date.AddDays(1), End = date.AddDays(1).AddHours(2), MyBool = true },
     new DerivedType() {  Start = date.AddDays(1), End = date.AddDays(1).AddHours(2), LongText = "Some looooooooooooooooooong text here" },
     new OtherType() { Start = date.AddDays(1), End = date.AddDays(1).AddHours(2), MyBool = true },
               new DerivedType() {  Start = date.AddDays(1), End = date.AddDays(1).AddHours(2), LongText = "Some looooooooooooooooooong text here" },
               new OtherType() { Start = date.AddDays(3), End = date.AddDays(3).AddHours(2), MyBool = true },
               new DerivedType() {  Start = date.AddDays(4), End = date.AddDays(4).AddHours(2), LongText = "Some looooooooooooooooooong text here" },
               new OtherType() { Start = date.AddDays(5), End = date.AddDays(5).AddHours(2), MyBool = true },
               new DerivedType() {  Start = date.AddDays(8), End = date.AddDays(8).AddHours(2), LongText = "Some looooooooooooooooooong text here" },
               new OtherType() { Start = date.AddDays(-1), End = date.AddDays(-1).AddHours(2), MyBool = true },
               new DerivedType() {  Start = date.AddDays(-3), End = date.AddDays(-3).AddHours(2), LongText = "Some looooooooooooooooooong text here" },
               new OtherType() { Start = date.AddDays(-5), End = date.AddDays(-5).AddHours(2), MyBool = true },
 
           };

1. BindingExpressionErrors (when switching from one day/week to another):

System.Windows.Data Error: 40 : BindingExpression path error: 'LongText' property not found on 'object' ''OtherType' (HashCode=24559820)'. BindingExpression:Path=Appointment.LongText; DataItem='AppointmentItemProxy' (HashCode=147525); target element is 'Label' (Name=''); target property is 'Content' (type 'Object')
System.Windows.Data Error: 40 : BindingExpression path error: 'MyBool' property not found on 'object' ''DerivedType' (HashCode=54588070)'. BindingExpression:Path=Appointment.MyBool; DataItem='AppointmentItemProxy' (HashCode=147525); target element is 'CheckBox' (Name=''); target property is 'IsChecked' (type 'Nullable`1')

2. Unrecognized Bindings in the xaml Editor (see attachment)

Even though the bindings do work, as we are working on software used in medical environment, binding errors are treated as exceptions because of quality regulations. Is there a way to resolve those?

 

 

0
Stefan
Telerik team
answered on 13 Mar 2018, 12:00 PM
Hi Roland,

Thank you for the update.

This behavior seems to be reproduced due to the virtualization mechanism of RadScheduleView, as when switching to another month the given datatemplate has a DataContext that is not the actual data type used. So, there are two possible solutions that I can suggest you. The first one would be to define the custom properties in the base type, instead of each inheritor. Please note, that when using custom Appointments, the Copy and CopyFrom methods would have to be overriden as well. I have modified the previous sample demonstrating the approach. You can also take a look at the Custom Appointment help article.

If you are not convenient with this approach, you can force the template of the Appointment to be cleared in order to ensure that the correct one is used. This can be achieved by defining a custom RadScheduleView and overriding its ClearAppointmentItemOverride method. The performance might be slightly affected with such an approach, as the default implementation of the control has a caching mechanism for the templates.
public class MyScheduleView : RadScheduleView
    {
        protected override void ClearAppointmentItemOverride(UIElement element)
        {
            base.ClearAppointmentItemOverride(element);
            (element as AppointmentItem).ContentTemplate = null;
        }
    }

I hope this helps. Let us know in case further assistance is needed.

Regards,
Stefan
Progress Telerik
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 allow you to write beautiful native mobile apps using a single shared C# codebase.
Tags
ScheduleView
Asked by
Roland
Top achievements
Rank 1
Answers by
Martin Ivanov
Telerik team
Roland
Top achievements
Rank 1
Stefan
Telerik team
Share this question
or