Script 4: Calendar in Studio for WinRT XAML

Download Trial with samples, if you do not already have Windows 8 Studio for WinRT XAML  

image

  

·         Calendar 

 

The Calendar control is unique to ComponentOne. No other vendor has this.

Create date-driven dashboards and scheduling apps with the ComponentOne Calendar™ for WinRT XAML. The C1Calendar control can be used for date navigation, date range selection, and it can display custom calendar information such as appointments.

Features

  • Gesture-based Month Navigation

By default, C1Calendar supports slide and flick gestures for month-to-month navigation. Or tap the navigation buttons to achieve the same effect.

  • Date Range Selection

Enable the user to select one day or many days through a default tap or hold and slide gesture. Control the number of days they can select using the MaxSelectionCount property.

  • Customizable Calendar Settings

Specify the starting day of the week, the work weekdays collection, and more. You can use C1Calendar with any supported culture in WinRT. Visually distinguish between work days and weekends through special brush properties. Make any date bolded to highlight it to the end-user.

  • Easy and Flexible Styling Model

With C1Calendar you can easily change control brushes without having to override templates. Each visible part of the control has its own brush, including adjacent days, weekends, selected days, the month header and more.

  • Customize Date Appearance and Content

You can alter the appearance of any individual day using a custom template and template selector. Use custom C1DataTemplateSelector implementations to display custom content within the date blocks, such as appointments from the device’s user data.

  • Show Week Numbers

Display week numbers by just setting one simple property. There are never any trailing empty weeks because C1Calendar always displays the minimum number of rows required per month whether it is 4, 5 or 6 weeks long.

 

   Getting Started with Calendar:

 

   Step 1 of 3: Creating an Application with a C1Calendar Control

In this step, you’ll create a Windows Phone application in Visual Studio using Calendar for Windows Phone.

Complete the following steps:

1.   In Visual Studio 2012 Select File | New | Project.

2.   In the New Project dialog box, expand a language in the left pane, under the language select Windows Metro style, and in the templates list select Blank App (XAML). Enter a Name and click OK to create your project.

 

3.   Navigate to the Toolbox and drag the C1Calendar icon to onto the design surface on to the grid. This will add the reference and XAML namespace automatically. The XAML markup resembles the following:

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
       <Calendar:C1Calendar />
    </Grid>

 

    4.  Add x:Name=”Calendar” Margin=”20″ Grid.Row=”0″ SelectedDateChanged=”Calendar_SelectedDateChanged” DayOfWeekFormat=”dddd” MaxSelectionCount=”21″ ShowWeekNumbers=”true” WeekendBrush=”Red” to the <Calendar:C1Calendar> tag to customize the control:

        <Calendar:C1Calendar x:Name="Calendar" Margin="20" Grid.Row="0" SelectedDateChanged="Calendar_SelectedDateChanged" DayOfWeekFormat="dddd" MaxSelectionCount="21" ShowWeekNumbers="true" WeekendBrush="Red" />

 

  

Add the following <Page.Resources> markup between the <Page>and <Grid> tags to define the templates that will be used to represent day slots in our C1Calendar control:

    <Page.Resources>
        <!-- return custom DataTemplates for calendar days -->
        <local:DaySlotTemplateSelector x:Key="DaySlotTemplateSelector">
            <Calendar:DaySlotTemplateSelector.Resources>
                <ResourceDictionary>
                    <DataTemplate x:Key="BoldedDay">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition />
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <!-- show appointments information saved in the DaySlot.Tag property -->
                            <Border Background="LightGreen" Grid.Row="0" VerticalAlignment="Top" >
                                <TextBlock Text="{Binding Tag}" Margin="5" TextWrapping="Wrap" Foreground="Black" />
                            </Border>
                            <TextBlock Text="{Binding}" Grid.Row="1" Foreground="OrangeRed" HorizontalAlignment="Left" VerticalAlignment="Bottom" FontWeight="SemiBold" Margin="6,0,0,4"/>
                        </Grid>
                    </DataTemplate>
                    <DataTemplate x:Key="UnboldedDay">
                        <TextBlock Text="{Binding}" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="6,22,0,4"/>
                    </DataTemplate>
                </ResourceDictionary>
            </Calendar:DaySlotTemplateSelector.Resources>
        </local:DaySlotTemplateSelector>
        <local:SmallDaySlotTemplateSelector x:Key="SmallDaySlotTemplateSelector">
            <Calendar:DaySlotTemplateSelector.Resources>
                <ResourceDictionary>
                    <DataTemplate x:Key="BoldedDay">
                        <TextBlock Text="{Binding}" HorizontalAlignment="Left" VerticalAlignment="Bottom" FontWeight="ExtraBlack" Margin="10,8,5,8"/>
                    </DataTemplate>
                    <DataTemplate x:Key="UnboldedDay">
                        <TextBlock Text="{Binding}" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="6,12,5,4"/>
                    </DataTemplate>
                </ResourceDictionary>
            </Calendar:DaySlotTemplateSelector.Resources>
        </local:SmallDaySlotTemplateSelector>
    </Page.Resources>

     This gives the control a name and customizes the formatting and appearance of the calendar’s day slots. In this example we are specifying the appearance of days that contain events. Note that you’ll add code for the referenced event handler to add events in a later step.

5.   Add the following markup above the Calendar between the <Grid Background=”{StaticResource ApplicationPageBackgroundThemeBrush}”> and Calendar:C1Calendar> tags. This XAML is not that important but it shows how you can handle different orientation states in your WinRT application. For example we are changing the date format depending on the orientation. If the app is in Snapped state, we will abbreviate the format and reduce margins.

 

        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <!--App Orientation States-->
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="OrientationStates">
                    <VisualState x:Name="Full"/>
                    <VisualState x:Name="Fill">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="Calendar">
                                <DiscreteObjectKeyFrame KeyTime="0">
                                    <DiscreteObjectKeyFrame.Value>
                                        <Thickness>15</Thickness>
                                    </DiscreteObjectKeyFrame.Value>
                                </DiscreteObjectKeyFrame>
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(C1Calendar.DayOfWeekFormat)" Storyboard.TargetName="Calendar">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="ddd"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="Portrait">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="Calendar">
                                <DiscreteObjectKeyFrame KeyTime="0">
                                    <DiscreteObjectKeyFrame.Value>
                                        <Thickness>15</Thickness>
                                    </DiscreteObjectKeyFrame.Value>
                                </DiscreteObjectKeyFrame>
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(C1Calendar.DayOfWeekFormat)" Storyboard.TargetName="Calendar">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="ddd"/>
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(C1Calendar.ShowWeekNumbers)" Storyboard.TargetName="Calendar">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="false"/>
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Visibility)" Storyboard.TargetName="SelectedDayInfo">
                                <DiscreteObjectKeyFrame KeyTime="0" >
                                    <DiscreteObjectKeyFrame.Value>
                                        <Visibility>Visible</Visibility>
                                    </DiscreteObjectKeyFrame.Value>
                                </DiscreteObjectKeyFrame>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="Snapped">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="Calendar">
                                <DiscreteObjectKeyFrame KeyTime="0">
                                    <DiscreteObjectKeyFrame.Value>
                                        <Thickness>5</Thickness>
                                    </DiscreteObjectKeyFrame.Value>
                                </DiscreteObjectKeyFrame>
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(C1Calendar.ShowWeekNumbers)" Storyboard.TargetName="Calendar">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="false"/>
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(C1Calendar.DayOfWeekFormat)" Storyboard.TargetName="Calendar">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="d"/>
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Visibility)" Storyboard.TargetName="SelectedDayInfo">
                                <DiscreteObjectKeyFrame KeyTime="0" >
                                    <DiscreteObjectKeyFrame.Value>
                                        <Visibility>Visible</Visibility>
                                    </DiscreteObjectKeyFrame.Value>
                                </DiscreteObjectKeyFrame>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
        </Grid>

6.   Let’s finish the rest of the UI. Add the following markup below the Calendar between the <Calendar:C1Calendar> and </Grid> tags:

 

        <Grid x:Name="SelectedDayInfo" Grid.Row="1" Height="120" Visibility="Collapsed" >
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <StackPanel Orientation="Horizontal" Margin="10" Grid.Row="0">
                <TextBlock Text="SelectedDate: "/>
                <TextBlock Text="{Binding SelectedDate, ElementName=Calendar}"/>
            </StackPanel>
            <TextBlock x:Name="dayInfo" Margin="10" Grid.Row="1" Foreground="Red"/>
        </Grid>


 

Step 2 of 3: Adding Data to the Calendar

In the last step, you added the C1Calendar control to the application. In this step, you will add a DataSeries object and data for it.

Complete the following steps to add data to the calendar programmatically:

1.   Select View | Code to switch to Code view.

2.   In MainPage.xaml.cs add code so it appears as follows:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.UI.ViewManagement;
using C1.Xaml;
using C1.Xaml.Calendar;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace Calendar
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private Dictionary<DateTime, string> _boldedDays = new Dictionary<DateTime, string>();
        private DaySlotTemplateSelector _dayTemplateSelector = null;
        private bool _loaded = false;
        public MainPage()
        {
            this.InitializeComponent();
        }
        void Calendar_SelectedDateChanged(object sender, DateChangedEventArgs e)
        {
            if (Calendar.SelectedDates.Count > 0 && _boldedDays.ContainsKey(Calendar.SelectedDates[0]))
            {
                dayInfo.Text = _boldedDays[Calendar.SelectedDates[0]];
            }
            else
            {
                dayInfo.Text = "";
            }
        }

        /// < summary>
        /// The DayTemplateSelector to use custom DataTemplate for bolded dates
        /// < /summary>
        private DaySlotTemplateSelector DayTemplateSelector
        {
            get
            {
                if (_dayTemplateSelector == null)
                {
                    _dayTemplateSelector = Resources["DaySlotTemplateSelector"] as DaySlotTemplateSelector;
                    if (_dayTemplateSelector != null)
                    {
                        _dayTemplateSelector.BoldedDays = this._boldedDays;
                    }
                }
                return _dayTemplateSelector;
            }
        }

        void Current_SizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e)
        {
            UpdateViewState();
        }

        private void UpdateViewState()
        {
            Calendar.ClearValue(HeightProperty);

            switch (ApplicationView.Value)
            {
                case ApplicationViewState.Filled:
                    Calendar.DaySlotTemplateSelector = DayTemplateSelector;
                    VisualStateManager.GoToState(this, "Fill", false);
                    break;

                case ApplicationViewState.FullScreenLandscape:
                    Calendar.DaySlotTemplateSelector = DayTemplateSelector;
                    VisualStateManager.GoToState(this, "Full", false);
                    break;

                case ApplicationViewState.Snapped:
                    // we have too few space, so use default DaySlotTemplateSelector
                    Calendar.Height = 400;
                    Calendar.DaySlotTemplateSelector = Resources["SmallDaySlotTemplateSelector"] as DataTemplateSelector;
                    VisualStateManager.GoToState(this, "Snapped", false);
                    break;

                case ApplicationViewState.FullScreenPortrait:
                    Calendar.DaySlotTemplateSelector = DayTemplateSelector;
                    VisualStateManager.GoToState(this, "Portrait", false);
                    break;

                default:
                    return;
            }
            Calendar.UpdateLayout();
        }

        /// < summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// < /summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            UpdateViewState();
            _loaded = true;
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            _loaded = false;
            base.OnNavigatedFrom(e);
        }

    }
  public class DaySlotTemplateSelector : C1.Xaml.Calendar.DaySlotTemplateSelector
    {
        public Dictionary<DateTime, string> BoldedDays = new Dictionary<DateTime, string>();

        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            DaySlot slot = item as DaySlot;
            if (slot != null && BoldedDays.ContainsKey(slot.Date))
            {
                // put appointments information into tag, so that it is possible to show it in a day DataTemplate
                slot.Tag = BoldedDays[slot.Date];
            }
            else
            {
                // clear appointments information
                slot.Tag = null;
            }
            if (slot != null && !slot.IsAdjacent && slot.DayOfWeek == DayOfWeek.Saturday)
            {
                // set color for Saturday
                ((Control)container).Foreground = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 0, 90, 255));
            }
            // the base class will select custom DataTemplate, defined in the DaySlotTemplateSelector.Resources collection (see MainPage.xaml file)
            return base.SelectTemplateCore(item, container);
        }
    }

    public class SmallDaySlotTemplateSelector : C1.Xaml.Calendar.DaySlotTemplateSelector
    {
        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            DaySlot slot = item as DaySlot;
            if (slot != null && !slot.IsAdjacent && slot.DayOfWeek == DayOfWeek.Saturday)
            {
                // set color for Saturday
                ((Control)container).Foreground = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 0, 90, 255));
            }
            // the base class will select custom DataTemplate, defined in the DaySlotTemplateSelector.Resources collection (see MainPage.xaml file)
            return base.SelectTemplateCore(item, container);
        }
    }

    public class DayOfWeekTemplateSelector : DataTemplateSelector
    {
        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            DayOfWeekSlot slot = item as DayOfWeekSlot;
            if (slot != null && slot.DayOfWeek == DayOfWeek.Saturday)
            {
                // set color for Saturday
                ((Control)container).Foreground = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 0, 90, 255));
            }
            // don't change DataTemplate at all
            return null;
        }

    }
}

In the next step, Step 3 of 3: Running the Calendar Application, you’ll examine the Calendar for WinRT XAML features.

 

Run it:

 

image

There is an example in our documentation for both VB and C#.

Next part in the blog series:

WinRT XAML (Part 5) Chart

Tags