We are using Format long which is HH:mm:ss. At the moment time picker allows user to enter/type more than 2 digits per hour, min, or second. But after submission it validates correctly as expected. It is same case with date digits as well.
So we made following changes to restrict this so that user can enter let's say 2 digits only. (Example: 10:20:00 ) instead of any (10xsfdfffsff:20:00).
Following works fine for majority of the cases. But I ran into one issue when I set my current time zone to Beijing, IsCurrentValueValid () method inside OnTextChanged() crashes -it throws stackoverflow exception. I had previously set my time zone to Pacific(PDT) and everything was working fine.
Please advise me if there is any simpler solution to achieve goal(user can enter/type only valid 2 digits for time).
```
public class MyDateTimeUpDown : Xceed.Wpf.Toolkit.DateTimeUpDown
{
private TextBox txtBox;
public override void OnApplyTemplate() {
base.OnApplyTemplate();
txtBox = Template.FindName("PART_TextBox", this) as TextBox;
}
private bool handle = true;
protected override void OnTextChanged(string previousValue, string currentValue)
{
if (!handle)
return;
base.OnTextChanged(previousValue, currentValue);
//Restrict users to enter only valid digits in each field.
// If not valid, set it back to its previous value
if (txtBox != null)
{
if (!IsCurrentValueValid())
{
handle = false;
int caret = txtBox.CaretIndex;
this.Text = previousValue;
txtBox.CaretIndex = caret;
handle = true;
return;
}
//DateTime parse exatly, therefore the format has to be exact.
string dateTimeFormat = GetFormatString(Format);
DateTime dt = DateTime.ParseExact(currentValue, dateTimeFormat, CultureInfo.CurrentCulture);
//Don't allow to user to input future datetime.
if (txtBox != null && IsGreaterThan(dt, DateTime.Now.ToUniversalTime()))
{
this.Text = previousValue;
return;
}
}
}
}
```
```
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<local:MyDateTimeUpDown x:Name="dateSelector" Grid.Column="0"
Format="ShortDate"
Value="{Binding Model.Timestamp, Mode=TwoWay, FallbackValue=4/14/2015}"/>
<c:SeDateTimeUpDown x:Name="timeSelector" Grid.Column="1"
Format="LongTime"
Value="{Binding Model.Timestamp, Mode=TwoWay, FallbackValue=12:00:00}"/>
```
So we made following changes to restrict this so that user can enter let's say 2 digits only. (Example: 10:20:00 ) instead of any (10xsfdfffsff:20:00).
Following works fine for majority of the cases. But I ran into one issue when I set my current time zone to Beijing, IsCurrentValueValid () method inside OnTextChanged() crashes -it throws stackoverflow exception. I had previously set my time zone to Pacific(PDT) and everything was working fine.
Please advise me if there is any simpler solution to achieve goal(user can enter/type only valid 2 digits for time).
```
public class MyDateTimeUpDown : Xceed.Wpf.Toolkit.DateTimeUpDown
{
private TextBox txtBox;
public override void OnApplyTemplate() {
base.OnApplyTemplate();
txtBox = Template.FindName("PART_TextBox", this) as TextBox;
}
private bool handle = true;
protected override void OnTextChanged(string previousValue, string currentValue)
{
if (!handle)
return;
base.OnTextChanged(previousValue, currentValue);
//Restrict users to enter only valid digits in each field.
// If not valid, set it back to its previous value
if (txtBox != null)
{
if (!IsCurrentValueValid())
{
handle = false;
int caret = txtBox.CaretIndex;
this.Text = previousValue;
txtBox.CaretIndex = caret;
handle = true;
return;
}
//DateTime parse exatly, therefore the format has to be exact.
string dateTimeFormat = GetFormatString(Format);
DateTime dt = DateTime.ParseExact(currentValue, dateTimeFormat, CultureInfo.CurrentCulture);
//Don't allow to user to input future datetime.
if (txtBox != null && IsGreaterThan(dt, DateTime.Now.ToUniversalTime()))
{
this.Text = previousValue;
return;
}
}
}
}
```
```
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<local:MyDateTimeUpDown x:Name="dateSelector" Grid.Column="0"
Format="ShortDate"
Value="{Binding Model.Timestamp, Mode=TwoWay, FallbackValue=4/14/2015}"/>
<c:SeDateTimeUpDown x:Name="timeSelector" Grid.Column="1"
Format="LongTime"
Value="{Binding Model.Timestamp, Mode=TwoWay, FallbackValue=12:00:00}"/>
```