Basic Calendar binding issue

10 posts, 0 answers
  1. Kyle
    Kyle avatar
    30 posts
    Member since:
    Dec 2014

    Posted 29 Apr 2015 Link to this post

    Hi,

     I'll preface this by saying i'm completely new to C#, MVVM, and Xamarin, so I apologize if this is an easy question.  I'm trying to implement the Telerik Calendar widget and have it bound to a DateTime object in my ViewModel.  I want user changes of clicking on a new date to trigger the change in the view model.  

     

    So i put break statements into the OnPropertyChanged function as well as the setter of SelectedDate.  I see am hitting those points only on the first run of my app, to the date that i declared in my ViewModel constructor.  I am expecting to get into the set method and the OnPropertyChanged everytime the user clicks on a new date on the calendar?  But that isn't happening so i'm clearly missing something.

     

    Thank you

     

    XAML Code:

    <?xml version="1.0" encoding="UTF-8"?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    x:Class="Mobile_Release_POC_4.MonthViewPage" 
    xmlns:local="clr-namespace:Mobile_Release_POC_4;assembly=Mobile_Release_POC_4"
    xmlns:telerikInput="clr-namespace:Telerik.XamarinForms.Input;assembly=Telerik.XamarinForms.Input"
    xmlns:sys="clr-namespace:System;assembly=mscorlib">

    <ContentPage.Resources>
        <ResourceDictionary>
            <local:OverallHealthToColorConverter x:Key="OverallHealthToColorConverter" />
        </ResourceDictionary>
      </ContentPage.Resources>


    <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition />
                    </Grid.RowDefinitions>

                   <telerikInput:RadCalendar 
                    Grid.Row="0"
            x:Name="calendarTest"
            SelectedDate="{Binding SelectedDate, Mode=TwoWay}"
                   ></telerikInput:RadCalendar>

     

     

    This is a piece of code from my code behind the Xaml setting up the BindingContext

     public MonthViewPage ()
    {
    InitializeComponent();
    this.BindingContext = new MonthViewViewModel();
    }

     

    Last here is my modalView

     

    public class MonthViewViewModel : INotifyPropertyChanged
    {

        public DateTime selectedDate{ get; set; }

        public event PropertyChangedEventHandler PropertyChanged;

        public MonthViewViewModel ()
        {
              SelectedDate = new DateTime (2015, 4, 15);
        }

         public DateTime SelectedDate
         {
                 protected set
         {
         if (!selectedDate.Equals(value))
         {
                selectedDate = value;
                OnPropertyChanged("SelectedDate");
         }
    }
        get { return selectedDate; }
    }

        protected void OnPropertyChanged(string propertyName)
       {
             if (PropertyChanged != null)
                     PropertyChanged(this,
                        new PropertyChangedEventArgs(propertyName));
        }

    }

  2. Rosy Topchiyska
    Admin
    Rosy Topchiyska avatar
    550 posts

    Posted 04 May 2015 Link to this post

    Hello Kyle,

    Thank you for writing.

    The problem is that the SelectedDate property should have a public setter, otherwise the binding wont work.

    I hope this helps. Please, let us know if you have further questions.

    Regards,
    Rosy Topchiyska
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
  3. DevCraft banner
  4. Kyle
    Kyle avatar
    30 posts
    Member since:
    Dec 2014

    Posted 06 May 2015 in reply to Rosy Topchiyska Link to this post

    Thank you for your response.  

     

    I have tried setting the setter to public, however that presents me with a build error of:

    'The accessibility modifier of the 'Mobile_Release_POC_4.MonthAndWeekViewModel.SelectedDate.set' accessor must be more restrictive than the property or indexer'

     

    Am I setting it up correctly in my Xaml?

  5. Rosy Topchiyska
    Admin
    Rosy Topchiyska avatar
    550 posts

    Posted 11 May 2015 Link to this post

    Hello Kyle,

    This is how your class could look like:
    public class MonthViewViewModel : INotifyPropertyChanged
    {
        private DateTime selectedDate;
      
        public MonthViewViewModel()
        {
            this.selectedDate = new DateTime(2015, 4, 15);
        }
      
        public event PropertyChangedEventHandler PropertyChanged;
      
        public DateTime SelectedDate
        {
            get
            {
                return this.selectedDate;
            }
            set
            {
                if (!this.selectedDate.Equals(value))
                {
                    this.selectedDate = value;
                    this.OnPropertyChanged();
                }
            }
        }
      
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

    A public property SelectedDate with private backing field selectedDate.

    Please, let us know if you have further questions.

    Regards,
    Rosy Topchiyska
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
  6. Kyle
    Kyle avatar
    30 posts
    Member since:
    Dec 2014

    Posted 11 May 2015 in reply to Rosy Topchiyska Link to this post

    Ok that did it!  Sorry it took that much work for me to get it, but as I said I'm still pretty new to Xamarin and MVVM.  I have another question regarding the calendar if you can answer it here that would be great, if not, I can make another forum post.

     

    Looking through the documentation, I haven't seen a way to tell if the user changes the month that they are viewing.  By clicking, holding, and moving up or down the user can change the month that is visible to them.  Is there a way to capture that event?  I know when they click on a date in the new month we can capture it, but i'm looking for a way to capture the fact that a month changes.

     

    I basically will grab a new set of data and need to alter the background colors of dates in that month, before they ever click on a new date.

     

    Thank you

  7. Kyle
    Kyle avatar
    30 posts
    Member since:
    Dec 2014

    Posted 11 May 2015 in reply to Kyle Link to this post

    I think I might have found it, please correct me if I'm wrong, but can the event DisplayDateChanged handle this use case?

     

    Thank you

  8. Kyle
    Kyle avatar
    30 posts
    Member since:
    Dec 2014

    Posted 12 May 2015 in reply to Kyle Link to this post

    So i'm now testing out EvaluateCellStyle and for the most part i'm having good success.  However, it seems like the date that is selected and today's date have their own style which always overrides the style that I had set for those days.  

     

    Is there a way to prevent today's date's styling or how can i override it, same with the selected date styling?

  9. Rosy Topchiyska
    Admin
    Rosy Topchiyska avatar
    550 posts

    Posted 14 May 2015 Link to this post

    Hello Kyle,

    There are some elements that do not support styling in the current version of RadCalendar control, but we have provided an endpoint to access the native calendars and modify them as per your needs. You can take a look at this article from our online documentation where you can find more information about how to override the default renderer.

    Here is an example:
    public class CustomCalendarRenderer : CalendarRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<RadCalendar> e)
        {
            base.OnElementChanged(e);
            this.Control.Adapter.TodayCellBackgroundColor = ColorExtensions.ToAndroid(Color.Red);
            this.Control.Adapter.TodayCellBorderColor = ColorExtensions.ToAndroid(Color.Yellow);
            this.Control.Adapter.SelectedCellBackgroundColor = ColorExtensions.ToAndroid(Color.Green);
            this.Control.CellDecorationsLayer.StrokeWidth = 5;
            this.Control.CellDecorationsLayer.Color = ColorExtensions.ToAndroid(Color.Blue);
        }
    }

    As for your previous question, the DisplayDate is a date from the current month. If the DisplayDateChanged event is fired, you can see if the month has changed if you check the month part of the new date.

    I hope this helps.

    Regards,
    Rosy Topchiyska
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  10. Kyle
    Kyle avatar
    30 posts
    Member since:
    Dec 2014

    Posted 14 May 2015 in reply to Rosy Topchiyska Link to this post

    Thank you for the responses.  So i'm still having issues with the custom renderer.  My end goal of this is to have all of the rest of the functionality of the calendar stay the same, but be able to just change the styling of Today and Selected Date cells.  When i try to implement your example I'm getting a key not found exception.  I implemented it as follows:

    01.using System;
    02.using System;
    03.using System.Collections.Generic;
    04.using System.Linq;
    05.using Telerik.XamarinForms.Common;
    06.using Telerik.XamarinForms.Input;
    07. 
    08.namespace Mobile_Release_POC_4
    09.{
    10.    public class CustomCalendar: RadCalendar
    11.    {
    12.        public CustomCalendar():base()
    13.        {
    14. 
    15.        }
    16. 
    17. 
    18.    }
    19.}

     

    In my android project:

    01.using System;
    02.using Mobile_Release_POC_4.Droid;
    03.using Telerik.XamarinForms.Input;
    04.using Telerik.XamarinForms.InputRenderer.Android;
    05.using Xamarin.Forms;
    06.using Xamarin.Forms.Platform.Android;
    07.using Com.Telerik.Widget.Calendar;
    08. 
    09.[assembly: ExportRenderer(typeof(Mobile_Release_POC_4.CustomCalendar), typeof(CustomCalendarRenderer))]
    10.namespace Mobile_Release_POC_4.Droid
    11.{
    12.    public class CustomCalendarRenderer: CalendarRenderer
    13.    {
    14.        protected override void OnElementChanged(ElementChangedEventArgs<RadCalendar> e)
    15.        {
    16.            base.OnElementChanged(e);
    17.            this.Control.Adapter.TodayCellBackgroundColor = ColorExtensions.ToAndroid(Color.Red);
    18.            this.Control.Adapter.TodayCellBorderColor = ColorExtensions.ToAndroid(Color.Yellow);
    19.            this.Control.Adapter.SelectedCellBackgroundColor = ColorExtensions.ToAndroid(Color.Green);
    20.            this.Control.CellDecorationsLayer.StrokeWidth = 5;
    21.            this.Control.CellDecorationsLayer.Color = ColorExtensions.ToAndroid(Color.Blue);
    22.        }
    23. 
    24.    }
    25.}

     

    This generates an exception.

     

    I also took a look at this forum post:http://www.telerik.com/forums/override-renderer

     By following the last comment in that thread I was able to get a custom calendar rendered, but it took away all of the default functionality and broke my bindings etc...  Is it not possible for me to just overwrite the styles of those cells while keeping everything else using the defaults?

     

    I have SelectedDate as a bound value, and I'm using EvaluateCellStyle function to add a background color to certain cell dates based on my data, so I don't want to break those while changing the styling of those few cells.

     

    Thank you

  11. Rosy Topchiyska
    Admin
    Rosy Topchiyska avatar
    550 posts

    Posted 19 May 2015 Link to this post

    Hi Kyle,

    The forum thread that you refer to demonstrates how to create a calendar + renderer from scratch, without using our infrastructure. The thread targets an earlier version of the controls where overriding the renderer was not possible and this was the only way to customize the native control.

    When overriding our CalendarRenderer, you have to use the RadCalendar control, not an inheriting class. We will update our documentation to make this clearer.

    I hope this makes things clearer. Let us know if you have any other questions.

    Regards,
    Rosy Topchiyska
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
DevCraft banner