Skip to content

Instantly share code, notes, and snippets.

@make4fun
Forked from qwertie/DateTimePicker.xaml
Last active September 19, 2021 07:45
Show Gist options
  • Save make4fun/257f7fa9a9e02738f42f3fb2f00cd216 to your computer and use it in GitHub Desktop.
Save make4fun/257f7fa9a9e02738f42f3fb2f00cd216 to your computer and use it in GitHub Desktop.
C# DateTimePicker for WPF
<UserControl x:Class="DTPicker.DateTimePicker"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:DTPicker"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d">
<UserControl.Resources>
<ControlTemplate x:Key="IconButton" TargetType="{x:Type ToggleButton}">
<Border>
<ContentPresenter />
</Border>
</ControlTemplate>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox BorderThickness="2" VerticalAlignment="Top" x:Name="DateDisplay" Width="155"
HorizontalAlignment="Stretch"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Center"
Height="26" IsReadOnly="True" IsUndoEnabled="False" Text="{Binding Source={x:Static sys:DateTime.Now}, StringFormat='{}{0:dd-MM-yyyy hh:mm tt}', Mode=OneWay}" >
</TextBox>
<ToggleButton Grid.Column="1" Template="{StaticResource IconButton}" MinHeight="25" MinWidth="25" Name="PopUpCalendarButton" IsChecked="False">
<Image Name="CalIco" Stretch="Fill" HorizontalAlignment="Left"/>
</ToggleButton>
<Popup IsOpen="{Binding Path=IsChecked, ElementName=PopUpCalendarButton}" x:Name="CalendarPopup" PopupAnimation="Fade" StaysOpen="False">
<Border Padding="2" Background="LightGray">
<StackPanel Orientation="Vertical" Background="LightGray">
<Calendar Margin="0,-3,0,0" x:Name="CalDisplay" DisplayDateStart="{Binding Source={x:Static sys:DateTime.Today}, Mode=OneWay}" SelectedDate="{x:Static sys:DateTime.Now}"/>
<StackPanel Orientation="Horizontal" Margin="0,-1,0,0">
<ComboBox Width="45" Name="Hours" HorizontalContentAlignment="Right" SelectedIndex="0">
<ComboBoxItem Content="0" />
<ComboBoxItem Content="1" />
<ComboBoxItem Content="2" />
<ComboBoxItem Content="3" />
<ComboBoxItem Content="4" />
<ComboBoxItem Content="5" />
<ComboBoxItem Content="6" />
<ComboBoxItem Content="7" />
<ComboBoxItem Content="8" />
<ComboBoxItem Content="9" />
<ComboBoxItem Content="10" />
<ComboBoxItem Content="11" />
</ComboBox>
<ComboBox Width="45" Name="Min" HorizontalContentAlignment="Right" SelectedIndex="0">
<ComboBoxItem Content="0" />
<ComboBoxItem Content="1" />
<ComboBoxItem Content="2" />
<ComboBoxItem Content="3" />
<ComboBoxItem Content="4" />
<ComboBoxItem Content="5" />
<ComboBoxItem Content="6" />
<ComboBoxItem Content="7" />
<ComboBoxItem Content="8" />
<ComboBoxItem Content="9" />
<ComboBoxItem Content="10" />
<ComboBoxItem Content="11" />
<ComboBoxItem Content="12" />
<ComboBoxItem Content="13" />
<ComboBoxItem Content="14" />
<ComboBoxItem Content="15" />
<ComboBoxItem Content="16" />
<ComboBoxItem Content="17" />
<ComboBoxItem Content="18" />
<ComboBoxItem Content="19" />
<ComboBoxItem Content="20" />
<ComboBoxItem Content="21" />
<ComboBoxItem Content="22" />
<ComboBoxItem Content="23" />
<ComboBoxItem Content="24" />
<ComboBoxItem Content="25" />
<ComboBoxItem Content="26" />
<ComboBoxItem Content="27" />
<ComboBoxItem Content="28" />
<ComboBoxItem Content="29" />
<ComboBoxItem Content="30" />
<ComboBoxItem Content="31" />
<ComboBoxItem Content="32" />
<ComboBoxItem Content="33" />
<ComboBoxItem Content="34" />
<ComboBoxItem Content="35" />
<ComboBoxItem Content="36" />
<ComboBoxItem Content="37" />
<ComboBoxItem Content="38" />
<ComboBoxItem Content="39" />
<ComboBoxItem Content="40" />
<ComboBoxItem Content="41" />
<ComboBoxItem Content="42" />
<ComboBoxItem Content="43" />
<ComboBoxItem Content="44" />
<ComboBoxItem Content="45" />
<ComboBoxItem Content="46" />
<ComboBoxItem Content="47" />
<ComboBoxItem Content="48" />
<ComboBoxItem Content="49" />
<ComboBoxItem Content="50" />
<ComboBoxItem Content="51" />
<ComboBoxItem Content="52" />
<ComboBoxItem Content="53" />
<ComboBoxItem Content="54" />
<ComboBoxItem Content="55" />
<ComboBoxItem Content="56" />
<ComboBoxItem Content="57" />
<ComboBoxItem Content="58" />
<ComboBoxItem Content="59" />
</ComboBox>
<ComboBox Width="45" Name="AMPM" HorizontalContentAlignment="Right" SelectedIndex="0">
<ComboBoxItem Content="AM"/>
<ComboBoxItem Content="PM"/>
</ComboBox>
<Button Name="SaveTime" Content="Save" Width="45" Click="SaveTime_Click"/>
</StackPanel>
</StackPanel>
</Border>
</Popup>
</Grid>
</UserControl>
using System;
using System.Drawing;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
namespace DTPicker
{
/// Why I made this fork =>
/// 1. I wanted to create a simple control with no external dependencies (which means not using WPFToolkit)
/// 2. I wanted to add time selection controls instead of using the adorners
/// 3. The textbox also allowed users to type whatever they wanted and then there were checks put in place
/// to track and correct them or to ask users to make corrections. Too complex in my view for a simple task
///
/// Changes Made =>
/// 1. Uses the WPF calendar control instead of the WPFToolkit calendar
/// 2. Uses dropdowns for selecting time and has a save button to update the textbox
///
/// Things that will be needed for this control to work properly (and look good :) ) =>
/// 1. A bitmap image 32x32 added as an embedded resource
///
/// Licensing =>
/// The Code Project Open License (CPOL)
/// http://www.codeproject.com/info/cpol10.aspx
public partial class DateTimePicker : UserControl
{
public DateTimePicker()
{
InitializeComponent();
CalDisplay.SelectedDatesChanged += CalDisplay_SelectedDatesChanged;
BitmapSource ConvertGDI_To_WPF(Bitmap bm)
{
BitmapSource bms = null;
IntPtr h_bm = IntPtr.Zero;
h_bm = bm.GetHbitmap();
bms = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(h_bm, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
bms.Freeze();
h_bm = IntPtr.Zero;
return bms;
}
Bitmap bitmap1 = Properties.Resources.datetime;
bitmap1.MakeTransparent(Color.Black);
CalIco.Source = ConvertGDI_To_WPF(bitmap1);
}
#region "EventHandlers"
private void CalDisplay_SelectedDatesChanged(object sender, EventArgs e)
{
PopUpCalendarButton.IsChecked = true;
if (Hours.SelectedIndex == -1 || Min.SelectedIndex == -1 || AMPM.SelectedIndex == -1)
{
var date = CalDisplay.SelectedDate.Value.Date + DateTime.Now.TimeOfDay;
DateDisplay.Text = date.ToString("dd-MM-yyyy hh:mm tt");
return;
}
if (AMPM.Text == "PM")
{
int hours = Convert.ToInt32(Hours.Text)+12;
TimeSpan timeSpan = TimeSpan.Parse(hours.ToString() + ":" + Min.Text);
if (CalDisplay.SelectedDate.Value.Date == DateTime.Today.Date && timeSpan.CompareTo(DateTime.Now.TimeOfDay)<0)
{
var date = CalDisplay.SelectedDate.Value.Date + DateTime.Now.TimeOfDay;
DateDisplay.Text = date.ToString("dd-MM-yyyy hh:mm tt");
}
else
{
var date = CalDisplay.SelectedDate.Value.Date + timeSpan;
DateDisplay.Text = date.ToString("dd-MM-yyyy hh:mm tt");
}
}
else
{
TimeSpan timeSpan = TimeSpan.Parse(Hours.Text + ":" + Min.Text);
if (CalDisplay.SelectedDate.Value.Date == DateTime.Today.Date && timeSpan.CompareTo(DateTime.Now.TimeOfDay) < 0)
{
var date = CalDisplay.SelectedDate.Value.Date + DateTime.Now.TimeOfDay;
DateDisplay.Text = date.ToString("dd-MM-yyyy hh:mm tt");
}
else
{
var date = CalDisplay.SelectedDate.Value.Date + timeSpan;
DateDisplay.Text = date.ToString("dd-MM-yyyy hh:mm tt");
}
}
}
private void SaveTime_Click(object sender, RoutedEventArgs e)
{
if (CalDisplay.SelectedDate.Value.Date == null)
{
CalDisplay.SelectedDate = DateTime.Today.Date;
CalDisplay.DisplayDate = DateTime.Today.Date;
}
if (Hours.SelectedIndex == -1 || Min.SelectedIndex == -1 || AMPM.SelectedIndex == -1) {}
else
{
CalDisplay_SelectedDatesChanged(SaveTime, EventArgs.Empty);
}
PopUpCalendarButton.IsChecked = false;
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment