DatePicker calendar popup today button

Feb 16, 2010 at 2:01 PM

How can I add a "Today" button to the calendar that pops up from the DatePicker control?  (clicking the "today" button would change the display date to the current date)

Feb 18, 2010 at 3:45 PM

SOLUTION:

ResourceDiction.xaml

 

<ResourceDictionary
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:wpft="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
	xmlns:primitives="clr-namespace:Microsoft.Windows.Controls.Primitives;assembly=WPFToolkit"
	xmlns:vsm="clr-namespace:System.Windows;assembly=WPFToolkit"
	xmlns:src="clr-namespace:WpfApplication1">
	<Style x:Key="TodayButtonCalendarStyle" TargetType="wpft:Calendar">
		<Setter Property="CalendarItemStyle" Value="{DynamicResource TodayButtonCalendarItemStyle}" />
	</Style>
	<Style x:Key="TodayButtonCalendarItemStyle" TargetType="primitives:CalendarItem">
		<Setter Property="Margin" Value="0,3,0,3" />
		<Setter Property="Template">
			<Setter.Value>
				<ControlTemplate TargetType="primitives:CalendarItem">
					<ControlTemplate.Resources>
						<!-- Start: Data template for header button -->
						<DataTemplate x:Key="DayTitleTemplate">
							<TextBlock FontWeight="Bold" FontFamily="Verdana" FontSize="9.5" Foreground="#FF333333" HorizontalAlignment="Center"
													 Text="{Binding}" Margin="0,6,0,6" VerticalAlignment="Center"/>
						</DataTemplate>
						<!-- End: Data template for header button -->
					</ControlTemplate.Resources>
					<Grid Name="PART_Root" >
						<Grid.Resources>
							<SolidColorBrush x:Key="DisabledColor" Color="#A5FFFFFF" />
						</Grid.Resources>
						<vsm:VisualStateManager.VisualStateGroups>
							<vsm:VisualStateGroup x:Name="CommonStates">
								<vsm:VisualState x:Name="Normal" />
								<vsm:VisualState x:Name="Disabled">
									<Storyboard>
										<DoubleAnimation Storyboard.TargetName="PART_DisabledVisual" Storyboard.TargetProperty="Opacity" To="1" Duration="0" />
									</Storyboard>
								</vsm:VisualState>
							</vsm:VisualStateGroup>
						</vsm:VisualStateManager.VisualStateGroups>
						<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" 
											Background="{TemplateBinding Background}" CornerRadius="1">
							<Border CornerRadius="1" BorderBrush="#FFFFFFFF" BorderThickness="2">
								<Grid>
									<Grid.RowDefinitions>
										<RowDefinition Height="Auto"/>
										<RowDefinition Height="*"/>
									</Grid.RowDefinitions>
									<Grid.ColumnDefinitions>
										<ColumnDefinition Width="Auto"/>
										<ColumnDefinition Width="Auto"/>
										<ColumnDefinition Width="Auto"/>
									</Grid.ColumnDefinitions>
									<Grid.Resources>
										<!-- Start: Previous button template -->
										<ControlTemplate x:Key="PreviousButtonTemplate" TargetType="Button">
											<Grid Cursor="Hand">
												<vsm:VisualStateManager.VisualStateGroups>
													<vsm:VisualStateGroup x:Name="CommonStates">
														<vsm:VisualState x:Name="Normal" />
														<vsm:VisualState x:Name="MouseOver">
															<Storyboard>
																<ColorAnimation Storyboard.TargetName="TextColor" Storyboard.TargetProperty="Color" To="#FF73A9D8" Duration="0" />
															</Storyboard>
														</vsm:VisualState>
														<vsm:VisualState x:Name="Disabled">
															<Storyboard>
																<DoubleAnimation Storyboard.TargetName="TextColor" Storyboard.TargetProperty="Opacity" To=".5" Duration="0" />
															</Storyboard>
														</vsm:VisualState>
													</vsm:VisualStateGroup>
												</vsm:VisualStateManager.VisualStateGroups>
												<Rectangle Fill="#11E5EBF1" Stretch="Fill" Opacity="1"/>
												<Grid>
													<Path Margin="14,-6,0,0" Height="10" Width="6" VerticalAlignment="Center" HorizontalAlignment="Left" Stretch="Fill" Data="M288.75,232.25 L288.75,240.625 L283,236.625 z">
														<Path.Fill>
															<SolidColorBrush x:Name="TextColor" Color="#FF333333" />
														</Path.Fill>
													</Path>
												</Grid>
											</Grid>
										</ControlTemplate>
										<!-- End: Previous button template -->
										<!-- Start: Next button template -->
										<ControlTemplate x:Key="NextButtonTemplate" TargetType="Button">
											<Grid Cursor="Hand">
												<vsm:VisualStateManager.VisualStateGroups>
													<vsm:VisualStateGroup x:Name="CommonStates">
														<vsm:VisualState x:Name="Normal" />
														<vsm:VisualState x:Name="MouseOver">
															<Storyboard>
																<ColorAnimation Storyboard.TargetName="TextColor" Storyboard.TargetProperty="Color" To="#FF73A9D8" Duration="0" />
															</Storyboard>
														</vsm:VisualState>
														<vsm:VisualState x:Name="Disabled">
															<Storyboard>
																<DoubleAnimation Storyboard.TargetName="TextColor" Storyboard.TargetProperty="Opacity" To=".5" Duration="0" />
															</Storyboard>
														</vsm:VisualState>
													</vsm:VisualStateGroup>
												</vsm:VisualStateManager.VisualStateGroups>
												<Rectangle Fill="#11E5EBF1" Stretch="Fill" Opacity="1"/>
												<Grid>
													<Path Margin="0,-6,14,0" Height="10" Width="6" VerticalAlignment="Center" HorizontalAlignment="Right" Stretch="Fill" Data="M282.875,231.875 L282.875,240.375 L288.625,236 z">
														<Path.Fill>
															<SolidColorBrush x:Name="TextColor" Color="#FF333333" />
														</Path.Fill>
													</Path>
												</Grid>
											</Grid>
										</ControlTemplate>
										<!-- End: Next button template -->
										<!-- Start: Header button template -->
										<ControlTemplate x:Key="HeaderButtonTemplate" TargetType="Button">
											<Grid Cursor="Hand">
												<vsm:VisualStateManager.VisualStateGroups>
													<vsm:VisualStateGroup x:Name="CommonStates">
														<vsm:VisualState x:Name="Normal" />
														<vsm:VisualState x:Name="MouseOver">
															<Storyboard>
																<ColorAnimation Storyboard.TargetName="TextColor" Storyboard.TargetProperty="Color" To="#FF73A9D8" Duration="0" />
															</Storyboard>
														</vsm:VisualState>
														<vsm:VisualState x:Name="Disabled">
															<Storyboard>
																<DoubleAnimation Storyboard.TargetName="buttonContent" Storyboard.TargetProperty="Opacity" To=".5" Duration="0" />
															</Storyboard>
														</vsm:VisualState>
													</vsm:VisualStateGroup>
												</vsm:VisualStateManager.VisualStateGroups>
												<ContentPresenter x:Name="buttonContent" Content="{TemplateBinding Content}"
																						ContentTemplate="{TemplateBinding ContentTemplate}" Margin="1,4,1,9"
																						HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
																						VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
													<TextElement.Foreground>
														<SolidColorBrush x:Name="TextColor" Color="#FF333333"/>
													</TextElement.Foreground>
												</ContentPresenter>
											</Grid>
										</ControlTemplate>
										<!-- End: Header button template -->
									</Grid.Resources>
									<!-- Start: Previous button content -->
									<Button x:Name="PART_PreviousButton" Grid.Row="0" Grid.Column="0" Template="{StaticResource PreviousButtonTemplate}" 
														Height="20" Width="28" HorizontalAlignment="Left" Focusable="False" />
									<!-- End: Previous button content -->
									<!-- Start: Header button content -->
									<Button x:Name="PART_HeaderButton" Grid.Row="0" Grid.Column="1" Template="{StaticResource HeaderButtonTemplate}" 
														HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" FontSize="10.5" Focusable="False" />
									<!-- End: Header button content -->
									<!-- Start: Next button content -->
									<Button x:Name="PART_NextButton" Grid.Row="0" Grid.Column="2" Height="20" Width="28" 
														HorizontalAlignment="Right" Template="{StaticResource NextButtonTemplate}" Focusable="False" />
									<!-- End: Next button content -->
									<!-- New for today button (Grid.Row & Grid.ColumnSpan lifted from PART_MonthView) -->
									<StackPanel Grid.Row="1" Grid.ColumnSpan="3" Grid.IsSharedSizeScope="True"
																Margin="6,-1,6,6" Orientation="Vertical">
										<!-- Start: Month Content Grid -->
										<Grid x:Name="PART_MonthView" Visibility="Visible">
											<Grid.RowDefinitions>
												<RowDefinition Height="Auto" SharedSizeGroup="SharedTitleHeight" />
												<RowDefinition Height="Auto" SharedSizeGroup="SharedItemHeight" />
												<RowDefinition Height="Auto" SharedSizeGroup="SharedItemHeight" />
												<RowDefinition Height="Auto" SharedSizeGroup="SharedItemHeight" />
												<RowDefinition Height="Auto" SharedSizeGroup="SharedItemHeight" />
												<RowDefinition Height="Auto" SharedSizeGroup="SharedItemHeight" />
												<RowDefinition Height="Auto" SharedSizeGroup="SharedItemHeight" />
											</Grid.RowDefinitions>
											<Grid.ColumnDefinitions>
												<ColumnDefinition Width="Auto"/>
												<ColumnDefinition Width="Auto"/>
												<ColumnDefinition Width="Auto"/>
												<ColumnDefinition Width="Auto"/>
												<ColumnDefinition Width="Auto"/>
												<ColumnDefinition Width="Auto"/>
												<ColumnDefinition Width="Auto"/>
											</Grid.ColumnDefinitions>
										</Grid>
										<!-- End: Month Content Grid -->
										<src:CalendarTodayButton Calendar="{Binding RelativeSource={RelativeSource AncestorType=wpft:Calendar}}" />
										<!-- New for today button -->
									</StackPanel>
									<!-- End of new for today button -->
									<!-- End: Year Content Grid -->
									<Grid x:Name="PART_YearView" Grid.Row="1" Grid.ColumnSpan="3" Visibility="Hidden" Margin="6,-3,7,6">
										<Grid.RowDefinitions>
											<RowDefinition Height="Auto"/>
											<RowDefinition Height="Auto"/>
											<RowDefinition Height="Auto"/>
										</Grid.RowDefinitions>
										<Grid.ColumnDefinitions>
											<ColumnDefinition Width="Auto"/>
											<ColumnDefinition Width="Auto"/>
											<ColumnDefinition Width="Auto"/>
											<ColumnDefinition Width="Auto"/>
										</Grid.ColumnDefinitions>
									</Grid>
									<!-- End: Year Content Grid -->
								</Grid>
							</Border>
						</Border>
						<Rectangle x:Name="PART_DisabledVisual" Opacity="0" Visibility="Collapsed" Stretch="Fill" StrokeThickness="1" RadiusX="2" RadiusY="2" Stroke="{StaticResource DisabledColor}" Fill="{StaticResource DisabledColor}"/>
					</Grid>
					<ControlTemplate.Triggers>
						<Trigger Property="IsEnabled" Value="False">
							<Setter TargetName="PART_DisabledVisual" Property="Visibility" Value="Visible" />
						</Trigger>
						<DataTrigger Value="Year">
							<DataTrigger.Binding>
								<Binding Path="DisplayMode">
									<Binding.RelativeSource>
										<RelativeSource Mode="FindAncestor" AncestorType="{x:Type wpft:Calendar}" />
									</Binding.RelativeSource>
								</Binding>
							</DataTrigger.Binding>
							<Setter TargetName="PART_MonthView" Property="Visibility" Value="Hidden" />
							<Setter TargetName="PART_YearView" Property="Visibility" Value="Visible" />
						</DataTrigger>
						<DataTrigger Value="Decade">
							<DataTrigger.Binding>
								<Binding Path="DisplayMode">
									<Binding.RelativeSource>
										<RelativeSource Mode="FindAncestor" AncestorType="{x:Type wpft:Calendar}" />
									</Binding.RelativeSource>
								</Binding>
							</DataTrigger.Binding>
							<Setter TargetName="PART_MonthView" Property="Visibility" Value="Hidden" />
							<Setter TargetName="PART_YearView" Property="Visibility" Value="Visible" />
						</DataTrigger>
					</ControlTemplate.Triggers>
				</ControlTemplate>
			</Setter.Value>
		</Setter>
	</Style>
</ResourceDictionary>

 

CalendarTodayButton.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Windows.Controls;
using Microsoft.Windows.Controls.Primitives;

namespace WpfApplication1
{
	public class CalendarTodayButton : Button
	{
		public static readonly DependencyProperty CalendarProperty = DependencyProperty.Register("Calendar", typeof(Calendar),
			typeof(CalendarTodayButton));

		public Calendar Calendar
		{
			set
			{
				SetValue(CalendarProperty, value);
			}
			get
			{
				return (Calendar)GetValue(CalendarProperty);
			}
		}

		public CalendarTodayButton()
		{
			Content = "Go to today";
			Width = 75;
			HorizontalAlignment = HorizontalAlignment.Right;
			Click += clkANSRCalendarTodayButton;
		}

		protected void clkANSRCalendarTodayButton(object sender, RoutedEventArgs e)
		{
			Calendar.DisplayDate = DateTime.Now.Date;
		}
	}
}

MainWindow.xaml

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:wpft="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
	x:Class="WpfApplication1.MainWindow"
	x:Name="Window" Title="MainWindow" Width="640" Height="480">
	<Window.Resources>
		<ResourceDictionary>
			<ResourceDictionary.MergedDictionaries>
				<ResourceDictionary Source="/ResourceDictionary.xaml" />
			</ResourceDictionary.MergedDictionaries>
		</ResourceDictionary>
	</Window.Resources>
	<Grid x:Name="LayoutRoot">
		<Grid.RowDefinitions>
			<RowDefinition Height="Auto" />
			<RowDefinition Height="Auto" />
			<RowDefinition Height="Auto" />
		</Grid.RowDefinitions>
		<wpft:Calendar Name="calTodayButton" Style="{DynamicResource TodayButtonCalendarStyle}" Grid.Row="0" />
		<wpft:Calendar Name="calTodayButton2" CalendarItemStyle="{DynamicResource TodayButtonCalendarItemStyle}" Grid.Row="1" />
		<wpft:DatePicker x:Name="dtpTest" CalendarStyle="{DynamicResource TodayButtonCalendarStyle}" Grid.Row="2" />
	</Grid>
</Window>