1
+ using System ;
2
+ using System . Windows ;
3
+ using System . Windows . Controls ;
4
+ using System . Windows . Controls . Primitives ;
5
+
6
+ namespace WPFDevelopers . Controls
7
+ {
8
+ [ TemplatePart ( Name = TimeSelectorTemplateName , Type = typeof ( ListBox ) ) ]
9
+ [ TemplatePart ( Name = EditableTextBoxTemplateName , Type = typeof ( TextBox ) ) ]
10
+ [ TemplatePart ( Name = PopupTemplateName , Type = typeof ( Popup ) ) ]
11
+ public class TimePicker : Control
12
+ {
13
+ private const string TimeSelectorTemplateName = "PART_TimeSelector" ;
14
+ private const string EditableTextBoxTemplateName = "PART_EditableTextBox" ;
15
+ private const string PopupTemplateName = "PART_Popup" ;
16
+
17
+ public static readonly DependencyProperty SelectedTimeFormatProperty =
18
+ DependencyProperty . Register ( "SelectedTimeFormat" , typeof ( string ) , typeof ( TimePicker ) ,
19
+ new PropertyMetadata ( "HH:mm:ss" ) ) ;
20
+
21
+ public static readonly DependencyProperty MaxDropDownHeightProperty =
22
+ DependencyProperty . Register ( "MaxDropDownHeight" , typeof ( double ) , typeof ( TimePicker ) ,
23
+ new UIPropertyMetadata ( SystemParameters . PrimaryScreenHeight / 3.0 , OnMaxDropDownHeightChanged ) ) ;
24
+
25
+ public static readonly DependencyProperty SelectedTimeProperty =
26
+ DependencyProperty . Register ( "SelectedTime" , typeof ( DateTime ? ) , typeof ( TimePicker ) ,
27
+ new PropertyMetadata ( null , OnSelectedTimeChanged ) ) ;
28
+
29
+ public static readonly DependencyProperty IsCurrentTimeProperty =
30
+ DependencyProperty . Register ( "IsCurrentTime" , typeof ( bool ) , typeof ( TimePicker ) , new PropertyMetadata ( false ) ) ;
31
+
32
+ private DateTime _date ;
33
+ private Popup _popup ;
34
+ private TextBox _textBox ;
35
+ private TimeSelector _timeSelector ;
36
+
37
+ static TimePicker ( )
38
+ {
39
+ DefaultStyleKeyProperty . OverrideMetadata ( typeof ( TimePicker ) ,
40
+ new FrameworkPropertyMetadata ( typeof ( TimePicker ) ) ) ;
41
+ }
42
+
43
+ public string SelectedTimeFormat
44
+ {
45
+ get => ( string ) GetValue ( SelectedTimeFormatProperty ) ;
46
+ set => SetValue ( SelectedTimeFormatProperty , value ) ;
47
+ }
48
+
49
+ public DateTime ? SelectedTime
50
+ {
51
+ get => ( DateTime ? ) GetValue ( SelectedTimeProperty ) ;
52
+ set => SetValue ( SelectedTimeProperty , value ) ;
53
+ }
54
+
55
+ public bool IsCurrentTime
56
+ {
57
+ get => ( bool ) GetValue ( IsCurrentTimeProperty ) ;
58
+ set => SetValue ( IsCurrentTimeProperty , value ) ;
59
+ }
60
+
61
+ private static void OnMaxDropDownHeightChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
62
+ {
63
+ var ctrl = d as TimePicker ;
64
+ if ( ctrl != null )
65
+ ctrl . OnMaxDropDownHeightChanged ( ( double ) e . OldValue , ( double ) e . NewValue ) ;
66
+ }
67
+
68
+ protected virtual void OnMaxDropDownHeightChanged ( double oldValue , double newValue )
69
+ {
70
+ }
71
+
72
+ private static void OnSelectedTimeChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
73
+ {
74
+ var ctrl = d as TimePicker ;
75
+ if ( ctrl != null && e . NewValue != null )
76
+ {
77
+ var dateTime = ( DateTime ) e . NewValue ;
78
+ if ( ctrl . _timeSelector != null && dateTime > DateTime . MinValue )
79
+ ctrl . _timeSelector . SelectedTime = dateTime ;
80
+ else
81
+ ctrl . _date = dateTime ;
82
+ }
83
+ }
84
+
85
+ public override void OnApplyTemplate ( )
86
+ {
87
+ base . OnApplyTemplate ( ) ;
88
+ _textBox = GetTemplateChild ( EditableTextBoxTemplateName ) as TextBox ;
89
+ _timeSelector = GetTemplateChild ( TimeSelectorTemplateName ) as TimeSelector ;
90
+ if ( _timeSelector != null )
91
+ {
92
+ _timeSelector . SelectedTimeChanged -= TimeSelector_SelectedTimeChanged ;
93
+ _timeSelector . SelectedTimeChanged += TimeSelector_SelectedTimeChanged ;
94
+ if ( ! SelectedTime . HasValue && IsCurrentTime )
95
+ {
96
+ SelectedTime = DateTime . Now ;
97
+ }
98
+ else
99
+ {
100
+ SelectedTime = null ;
101
+ SelectedTime = _date ;
102
+ }
103
+ }
104
+
105
+ _popup = GetTemplateChild ( PopupTemplateName ) as Popup ;
106
+ if ( _popup != null )
107
+ {
108
+ _popup . Opened -= Popup_Opened ;
109
+ _popup . Opened += Popup_Opened ;
110
+ }
111
+ }
112
+
113
+ private void Popup_Opened ( object sender , EventArgs e )
114
+ {
115
+ if ( _timeSelector != null )
116
+ _timeSelector . SetTime ( ) ;
117
+ }
118
+
119
+ private void TimeSelector_SelectedTimeChanged ( object sender , RoutedPropertyChangedEventArgs < DateTime ? > e )
120
+ {
121
+ if ( _textBox != null && e . NewValue != null )
122
+ {
123
+ _textBox . Text = e . NewValue . Value . ToString ( SelectedTimeFormat ) ;
124
+ SelectedTime = e . NewValue ;
125
+ }
126
+ }
127
+ }
128
+ }
0 commit comments