Skip to content

Commit 988d5db

Browse files
chris84948chris84948
authored andcommitted
TimePicker now falls back to previous valid value
Changes made to force behavior of TimePicker to more closely follow the behavior of the DatePicker control. When there is previously a good value selected for the time and the user then enters an invalid time, the time will fall back to the previous good value. The time parsing has also been opened up to allow more formats.
1 parent e1d83ca commit 988d5db

File tree

1 file changed

+49
-14
lines changed

1 file changed

+49
-14
lines changed

MaterialDesignThemes.Wpf/TimePicker.cs

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ public class TimePicker : Control
2525
private Popup _popup;
2626
private Button _dropDownButton;
2727
private bool _disablePopupReopen;
28+
private DateTime? _lastValidTime;
2829

29-
static TimePicker()
30+
static TimePicker()
3031
{
3132
DefaultStyleKeyProperty.OverrideMetadata(typeof(TimePicker), new FrameworkPropertyMetadata(typeof(TimePicker)));
3233
}
@@ -67,10 +68,11 @@ public string Text
6768
private static void SelectedTimePropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
6869
{
6970
var timePicker = (TimePicker) dependencyObject;
70-
timePicker.SetCurrentValue(TextProperty, timePicker.DateTimeToString(timePicker.SelectedTime));
71-
}
71+
timePicker.SetCurrentValue(TextProperty, timePicker.DateTimeToString(timePicker.SelectedTime));
72+
timePicker._lastValidTime = timePicker.SelectedTime;
73+
}
7274

73-
public DateTime? SelectedTime
75+
public DateTime? SelectedTime
7476
{
7577
get { return (DateTime?) GetValue(SelectedTimeProperty); }
7678
set { SetValue(SelectedTimeProperty, value); }
@@ -212,10 +214,36 @@ public override void OnApplyTemplate()
212214

213215
private void TextBoxOnLostFocus(object sender, RoutedEventArgs routedEventArgs)
214216
{
215-
SetSelectedTime();
216-
}
217+
if (_textBox == null) return;
218+
219+
if (!string.IsNullOrEmpty(_textBox.Text))
220+
{
221+
DateTime time;
222+
if (IsTimeValid(_textBox.Text, out time))
223+
SetCurrentValue(SelectedTimeProperty, time);
224+
225+
else // Invalid time, jump back to previous good time
226+
SetInvalidTime();
227+
}
228+
}
229+
230+
private void SetInvalidTime()
231+
{
232+
if (_lastValidTime != null)
233+
{
234+
SetCurrentValue(SelectedTimeProperty, (DateTime)_lastValidTime);
235+
_textBox.Text = SelectedTime.Value.ToString(SelectedTime.Value.Hour % 12 > 9 ? "hh:mm tt" : "h:mm tt");
236+
}
237+
238+
else
239+
{
240+
SetCurrentValue(SelectedTimeProperty, null);
241+
_textBox.Text = "";
242+
}
217243

218-
private void TextBoxOnKeyDown(object sender, KeyEventArgs keyEventArgs)
244+
}
245+
246+
private void TextBoxOnKeyDown(object sender, KeyEventArgs keyEventArgs)
219247
{
220248
keyEventArgs.Handled = ProcessKey(keyEventArgs) || keyEventArgs.Handled;
221249
}
@@ -255,8 +283,9 @@ private bool ProcessKey(KeyEventArgs keyEventArgs)
255283

256284
private void TextBoxOnTextChanged(object sender, TextChangedEventArgs textChangedEventArgs)
257285
{
258-
SetCurrentValue(TextProperty, _textBox.Text);
259-
}
286+
if (_popup?.IsOpen == true)
287+
SetCurrentValue(TextProperty, _textBox.Text);
288+
}
260289

261290
private void SetSelectedTime()
262291
{
@@ -268,18 +297,24 @@ private void SetSelectedTime()
268297
}
269298
}
270299

271-
private static void ParseTime(string s, Action<DateTime> successContinuation)
300+
private void ParseTime(string s, Action<DateTime> successContinuation)
272301
{
273302
var dtfi = CultureInfo.CurrentCulture.GetDateFormat();
274303

275304
DateTime time;
276-
if (DateTime.TryParseExact(
277-
s, new [] { dtfi.ShortTimePattern, dtfi.LongTimePattern },
278-
CultureInfo.CurrentCulture, DateTimeStyles.None, out time))
305+
if (IsTimeValid(s, out time))
279306
successContinuation(time);
280307
}
281308

282-
private string DateTimeToString(DateTime? d)
309+
private bool IsTimeValid(string s, out DateTime time)
310+
{
311+
return DateTime.TryParse(s,
312+
CultureInfo.CurrentCulture,
313+
DateTimeStyles.AssumeLocal | DateTimeStyles.AllowWhiteSpaces,
314+
out time);
315+
}
316+
317+
private string DateTimeToString(DateTime? d)
283318
{
284319
return d.HasValue ? DateTimeToString(d.Value) : null;
285320
}

0 commit comments

Comments
 (0)