For didactic purpose I have started to create a calendar mark-up for Windows Phone using Silverlight technology. Silverlight is native for Windows Phone and this is one of the reasons I choose it. The final scope is to have something like this.

CalendarWindowsPhone

First step you need to do is to add a user control in your project. In my case I have created a folder called Controls and inside it I have added a user control called Calendar. After this step is done, is time to move to the calendar logic itself. First of all, you need a grid with 7 columns and 8 rows. 7 columns because I we have only seven days is an week and 8 rows you need for the following distribution:
– 1st row is containing buttons for navigation to previous or next month and to display selected month and year.
– 2nd row is containing days of the week.
– Rows 3,4,5,6,7 are containing dates for selected month
– Last row is for displaying additional data based on selected date. It’s all about developers imagination what data wants to display and how and I won’t talk about this.

The CAML code is simple. You can note the grid, days of the week displayed in blocks of text wrapped in borders controls and a long list selector which can be used to display additional date.

<UserControl xmlns:Controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"  x:Class="PhoneCorporateApplication.Controls.Calendar"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:sharecontrols="clr-namespace:PhoneCorporateApplication.Controls"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    d:DesignHeight="480" d:DesignWidth="480">
    
    <Grid x:Name="LayoutRoot"  Background="#000" Loaded="LayoutRoot_Loaded">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"></ColumnDefinition>
            <ColumnDefinition Width="1*"></ColumnDefinition>
            <ColumnDefinition Width="1*"></ColumnDefinition>
            <ColumnDefinition Width="1*"></ColumnDefinition>
            <ColumnDefinition Width="1*"></ColumnDefinition>
            <ColumnDefinition Width="1*"></ColumnDefinition>
            <ColumnDefinition Width="1*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"  />
            <RowDefinition Height="Auto"  />
            <RowDefinition Height="Auto" x:Name="FirstWeek"  />
            <RowDefinition Height="Auto" x:Name="SecondWeek"  />
            <RowDefinition Height="Auto" x:Name="ThirdWeek"  />
            <RowDefinition Height="Auto" x:Name="FourthWeek"  />
            <RowDefinition Height="Auto" x:Name="FifthWeek"  />
            <RowDefinition Height="Auto" x:Name="SixthWeek"  />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>


        <Button Grid.Row="0" Grid.Column="0" Name="btnPrevMonth"  Content="&lt;" BorderThickness="0" Click="btnPrevMonth_Click" />
        <TextBlock Name="txtMonthAndYear" Text="" VerticalAlignment="Center" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="5" TextAlignment="Center"  />
        <Button Grid.Row="0" Grid.Column="6" Name="btnNextMonth"  Content="&gt;" BorderThickness="0" Click="btnNextMonth_Click" />


        <!-- Calendar days-->
        <Border Grid.Column="0" Grid.Row="1" Background="BlueViolet" CornerRadius="4" Margin="2">
            <TextBlock Text="Su" Style="{StaticResource CalendarDays}" />
        </Border>
        <Border Grid.Column="1" Grid.Row="1" Background="BlueViolet" CornerRadius="4" Margin="2">
            <TextBlock  Text="Mo" Style="{StaticResource CalendarDays}" />
        </Border>
        <Border Grid.Column="2" Grid.Row="1" Background="BlueViolet" CornerRadius="4" Margin="2">
            <TextBlock Text="Tu" Style="{StaticResource CalendarDays}" />
        </Border>
        <Border Grid.Column="3" Grid.Row="1" Background="BlueViolet" CornerRadius="4" Margin="2">
            <TextBlock Text="We" Style="{StaticResource CalendarDays}"  />
        </Border>
        <Border Grid.Column="4" Grid.Row="1" Background="BlueViolet" CornerRadius="4" Margin="2">
            <TextBlock Grid.Column="4" Grid.Row="0" Text="Th" Style="{StaticResource CalendarDays}"  />
        </Border>
        <Border Grid.Column="5" Grid.Row="1" Background="BlueViolet" CornerRadius="4" Margin="2">
            <TextBlock Grid.Column="5" Grid.Row="0" Text="Fr" Style="{StaticResource CalendarDays}" />
        </Border>
        <Border Grid.Column="6" Grid.Row="1" Background="BlueViolet" CornerRadius="4" Margin="2">
            <TextBlock Grid.Column="6" Grid.Row="0" Text="Sa" Style="{StaticResource CalendarDays}" />
        </Border>
         <StackPanel Orientation="Horizontal" Grid.Row="8" Grid.Column="0" Grid.ColumnSpan="7">

            <Controls:LongListSelector Name="ViewEvents">
              
            </Controls:LongListSelector>
         
         </StackPanel>


    </Grid>
</UserControl>

From this code we missed dates for selected months, but this will be added dynamically from the code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;

namespace PhoneCorporateApplication.Controls
{
    public partial class Calendar : UserControl
    {
        /// <summary>
        /// Months names
        /// </summary>
        string[] months = new string[12] { "January","February","March","April","May","June","July","August","September","October","November","December" };
        
        /// <summary>
        /// Selected month
        /// </summary>
        int selectedMonth;
        /// <summary>
        /// Selected year
        /// </summary>
        int selectedYear;


        /// <summary>
        /// Draw calendar mark-up
        /// </summary>
        /// 
        /// 
        public void DrawCalendar(int year, int month)
        {
            
            CleanCalendar();
       

            this.selectedMonth = month;
            this.selectedYear = year;

            DateTime firstDay = new DateTime(year, month, 1);
            DateTime lastDay = new DateTime(year, month, DateTime.DaysInMonth(year, month));

            int week = 2;
            while (firstDay &lt;= lastDay)
            {
                var txtCalendarDate = new TextBlock();
                txtCalendarDate.Style = Application.Current.Resources[&quot;CalendarDates&quot;] as Style;
                txtCalendarDate.Text = Convert.ToString(firstDay.Day);
               
                txtCalendarDate.Loaded += txtCalendarDate_Loaded;
                txtCalendarDate.Tap += txtCalendarDate_Tap;
               

                // Create border arround date
                Border calendarDateBorder = new Border();
                calendarDateBorder.Style = Application.Current.Resources[&quot;CalendarDateBackground&quot;] as Style;
                calendarDateBorder.Child = txtCalendarDate;

                Grid.SetRow(calendarDateBorder, week);
                Grid.SetColumn(calendarDateBorder, Convert.ToInt16(firstDay.DayOfWeek));
                this.LayoutRoot.Children.Add(calendarDateBorder);
       
              
                if (firstDay.DayOfWeek == DayOfWeek.Saturday)
                {
                    week++;
                }
                firstDay = firstDay.AddDays(1);
            }


            this.txtMonthAndYear.Text = this.months.ElementAt(month - 1) + &quot; - &quot; + year;  
        }

        void txtCalendarDate_Loaded(object sender, RoutedEventArgs e)
        {
           
        }

        void txtCalendarDate_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            TextBlock txtCalendarDate = (TextBlock)sender;
            
        }


        public Calendar()
        {
            InitializeComponent();
        }

        private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
        {
            DrawCalendar(System.DateTime.Today.Year, System.DateTime.Today.Month);
        }


        /// <summary>
        /// Go to next month
        /// </summary>
        /// 
        /// 
        private void btnNextMonth_Click(object sender, RoutedEventArgs e)
        {
            CleanCalendar();
 
            if(this.selectedMonth == 12) {
                this.DrawCalendar(this.selectedYear + 1, 1);
            }
            else {
                this.DrawCalendar(this.selectedYear, this.selectedMonth + 1);
            }
        
        
        }

        /// <summary>
        /// Go to previous month
        /// </summary>
        /// 
        /// 
        private void btnPrevMonth_Click(object sender, RoutedEventArgs e)
        {
            CleanCalendar();
            if(this.selectedMonth == 1)
            {
                this.DrawCalendar(this.selectedYear - 1, 12);
            }
            else
            {
                this.DrawCalendar(this.selectedYear, this.selectedMonth - 1);
            }
        }


        /// <summary>
        /// Clean existing calendar data before render new mark-up
        /// </summary>
        private void CleanCalendar()
        {
            int[] rows = new int[6] { 2, 3, 4, 5, 6, 7 };
            for(int i = 0; i  0)
            {
                LayoutRoot.Children.Remove(eList.First());
            }
        }

    }
} 

The main method is DrawCalendar which accepts two integer parameters: year and month. When the user control is loaded it is called with year and month for current date. Previous and next month buttons are calling it with different parameters by adding or decreasing month and year properties with 1 month. There is method bind to tap even for each block of text representing dates of month. Depending of requirements, implementation should be done here.

Advertisements