-
-
Save Apflkuacha/406e755c8b42a70b7ab138e6b985bcdf to your computer and use it in GitHub Desktop.
C# DateTimePicker for WPF
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<UserControl x:Class="Controls.DateTimePicker" | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |
xmlns:sys="clr-namespace:System;assembly=mscorlib" | |
mc:Ignorable="d"> | |
<UserControl.Resources> | |
<ResourceDictionary> | |
<controls:InvertBoolConverter x:Key="InvertBoolConverter" /> | |
</ResourceDictionary> | |
</UserControl.Resources> | |
<Grid> | |
<Grid.RowDefinitions> | |
<RowDefinition Height="*" /> | |
<RowDefinition Height="*" /> | |
</Grid.RowDefinitions> | |
<ToggleButton Grid.Column="0" MinHeight="25" MinWidth="25" Name="PopUpCalendarButton" IsChecked="False" IsHitTestVisible="{Binding IsOpen, ElementName=CalendarPopup, Mode=OneWay, Converter={StaticResource InvertBoolConverter}}"> | |
<ToggleButton.Style> | |
<Style TargetType="{x:Type ToggleButton}"> | |
<Setter Property="Background" Value="White" /> | |
<Setter Property="Template"> | |
<Setter.Value> | |
<ControlTemplate TargetType="{x:Type ToggleButton}"> | |
<Border Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="1"> | |
<ContentPresenter /> | |
</Border> | |
</ControlTemplate> | |
</Setter.Value> | |
</Setter> | |
</Style> | |
</ToggleButton.Style> | |
<Grid> | |
<Grid.ColumnDefinitions> | |
<ColumnDefinition Width="2*" /> | |
<ColumnDefinition Width="Auto" /> | |
</Grid.ColumnDefinitions> | |
<TextBox BorderThickness="0" Height="26" x:Name="DateDisplay" VerticalAlignment="Center" | |
HorizontalAlignment="Left" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" | |
IsHitTestVisible="False" IsReadOnly="True" IsUndoEnabled="False" /> | |
<Image Grid.Column="1" Name="CalIco" Stretch="Fill" HorizontalAlignment="Right" /> | |
</Grid> | |
</ToggleButton> | |
<Popup IsOpen="{Binding Path=IsChecked, ElementName=PopUpCalendarButton}" x:Name="CalendarPopup" PopupAnimation="Fade" StaysOpen="False" Width="180"> | |
<Border Padding="2" Background="White"> | |
<Grid> | |
<Grid.ColumnDefinitions> | |
<ColumnDefinition Width="2*" /> | |
<ColumnDefinition Width="2*" /> | |
<ColumnDefinition Width="3*" /> | |
</Grid.ColumnDefinitions> | |
<Grid.RowDefinitions> | |
<RowDefinition Height="*" /> | |
<RowDefinition Height="Auto" /> | |
</Grid.RowDefinitions> | |
<Calendar Grid.ColumnSpan="3" Margin="0,-3,0,0" x:Name="CalDisplay" DisplayDateStart="{Binding Source={x:Static sys:DateTime.Today}, Mode=OneWay}" SelectedDate="{x:Static sys:DateTime.Now}" PreviewMouseUp="CalDisplay_PreviewMouseUp" /> | |
<ComboBox Grid.Row="1" Grid.Column="0" Name="Hours" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" SelectedIndex="8" SelectionChanged="Time_SelectionChanged"> | |
<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" /> | |
</ComboBox> | |
<ComboBox Grid.Row="1" Grid.Column="1" Name="Min" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" SelectedIndex="0" SelectionChanged="Time_SelectionChanged"> | |
<ComboBoxItem Content="0" /> | |
<ComboBoxItem Content="10" /> | |
<ComboBoxItem Content="20" /> | |
<ComboBoxItem Content="30" /> | |
<ComboBoxItem Content="40" /> | |
<ComboBoxItem Content="50" /> | |
</ComboBox> | |
<Button Grid.Row="1" Grid.Column="2" Name="SaveTime" Content="OK" Click="SaveTime_Click" /> | |
</Grid> | |
</Border> | |
</Popup> | |
</Grid> | |
</UserControl> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Drawing; | |
using System.Windows; | |
using System.Windows.Controls; | |
using System.Windows.Controls.Primitives; | |
using System.Windows.Data; | |
using System.Windows.Input; | |
using System.Windows.Media.Imaging; | |
namespace Controls | |
{ | |
/// Changes and improvements made => | |
/// 1. Removed AM/PM chooser and made time selectable from 6:00 to 18:00 | |
/// 2. Popup improvements | |
/// 3. Added SelectedDate DependencyProperty | |
/// | |
/// 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 | |
{ | |
private const string DateTimeFormat = "dd.MM.yyyy HH:mm"; | |
#region "Properties" | |
public DateTime SelectedDate | |
{ | |
get => (DateTime)GetValue(SelectedDateProperty); | |
set => SetValue(SelectedDateProperty, value); | |
} | |
#endregion | |
#region "DependencyProperties" | |
public static readonly DependencyProperty SelectedDateProperty = DependencyProperty.Register("SelectedDate", | |
typeof(DateTime), typeof(DateTimePicker), new FrameworkPropertyMetadata(DateTime.Now, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); | |
#endregion | |
public DateTimePicker() | |
{ | |
InitializeComponent(); | |
CalDisplay.SelectedDatesChanged += CalDisplay_SelectedDatesChanged; | |
CalDisplay.SelectedDate = DateTime.Now.AddDays(1); | |
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.DateTimePicker; | |
bitmap1.MakeTransparent(Color.Black); | |
CalIco.Source = ConvertGDI_To_WPF(bitmap1); | |
} | |
#region "EventHandlers" | |
private void CalDisplay_SelectedDatesChanged(object sender, EventArgs e) | |
{ | |
var hours = (Hours?.SelectedItem as ComboBoxItem)?.Content?.ToString() ?? "0"; | |
var minutes = (Min?.SelectedItem as ComboBoxItem)?.Content?.ToString() ?? "0"; | |
TimeSpan timeSpan = TimeSpan.Parse(hours + ":" + minutes); | |
if (CalDisplay.SelectedDate.Value.Date == DateTime.Today.Date && timeSpan.CompareTo(DateTime.Now.TimeOfDay) < 0) | |
{ | |
timeSpan = TimeSpan.FromHours(DateTime.Now.Hour + 1); | |
} | |
var date = CalDisplay.SelectedDate.Value.Date + timeSpan; | |
DateDisplay.Text = date.ToString(DateTimeFormat); | |
SelectedDate = date; | |
} | |
private void SaveTime_Click(object sender, RoutedEventArgs e) | |
{ | |
CalDisplay_SelectedDatesChanged(SaveTime, EventArgs.Empty); | |
PopUpCalendarButton.IsChecked = false; | |
} | |
private void Time_SelectionChanged(object sender, SelectionChangedEventArgs e) | |
{ | |
CalDisplay_SelectedDatesChanged(sender, e); | |
} | |
private void CalDisplay_PreviewMouseUp(object sender, MouseButtonEventArgs e) | |
{ // that it's not necessary to click twice after opening the calendar https://stackoverflow.com/q/6024372 | |
if (Mouse.Captured is CalendarItem) | |
{ | |
Mouse.Capture(null); | |
} | |
} | |
#endregion | |
} | |
[ValueConversion(typeof(bool), typeof(bool))] | |
public class InvertBoolConverter : IValueConverter | |
{ | |
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) | |
{ | |
if (targetType != typeof(bool)) | |
throw new InvalidOperationException("The target must be a boolean"); | |
return !(bool)value; | |
} | |
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) | |
{ | |
if (targetType != typeof(bool)) | |
throw new InvalidOperationException("The target must be a boolean"); | |
return !(bool)value; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment