12-11-2020 08:11 AM
Hi,
What is the difference between TimeStampTextBoxDateTime and TimeStampTextBoxPrecisionDateTime? I am using the TimeStampTextBoxDateTime, but still gets the milliseconds displayed. Is there any way to remove this?
12-13-2020 05:08 PM
The precision time types allows more precise values to be displayed, but in both cases the final displayed value is determined by the ValueFormatter
. You can use any of the standard or custom .NET date and time format strings to display values (I believe the long pattern is used by default).
For example, you could specify the short general pattern to display the time down to minutes (set here in XAML):
<ni:TimeStampTextBoxDateTime ValueFormatter="g" />
Or a custom pattern to show seconds without any fractions of a second (set here using code):
control.ValueFormatter = new TimeValueFormatter { Format = "yyyy-MM-dd H:mm:ss" };
01-05-2021 12:41 PM
Thanks Paul,
The ValueFormatter solution works good! However, I noticed another issue. The format used inside the calendar is US DateTime, whereas the textbox use regional DateTime settings (see picture). Is this a bug? Is there a solution to this?
Calendar
01-06-2021 02:11 PM
The date time popup uses the same general format for all values. There is no direct way to configure this on the control, but you can use a custom control template to change the value in the popup:
<Style TargetType="niPrimitives:DateTimePickerDateTime">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="niPrimitives:DateTimePickerDateTime">
<StackPanel Orientation="Vertical">
<Calendar x:Name="PART_DatePickerCalendar"
Margin="6,3"
DisplayDate="{Binding CurrentDisplayDate, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
IsTodayHighlighted="False"
SelectedDate="{Binding CurrentSelectedDate, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" />
<Grid Margin="3,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" VerticalAlignment="Center" FontSize="9" Text="Date
and
Time" TextAlignment="Center" TextWrapping="Wrap" />
<TextBox x:Name="PART_DateTimeTextBox"
Grid.Column="1"
Margin="3,0"
Padding="1,0"
Text="{Binding CurrentDateTime, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, StringFormat=\{0:h:mm:ss.FFF tt
MM/dd/yyyy\}}"
TextAlignment="Right"
TextWrapping="Wrap" />
<Button x:Name="PART_NowButton" Grid.Column="2" Margin="3,0" Padding="6,2" VerticalContentAlignment="Center" Content="Now" />
</Grid>
<StackPanel Margin="3" HorizontalAlignment="Right" Orientation="Horizontal">
<Button x:Name="PART_CommitButton" Margin="3" Padding="6,2" Content="OK" IsDefault="True" />
<Button x:Name="PART_CancelButton" Margin="3" Padding="6,2" Content="Cancel" IsCancel="True" />
</StackPanel>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The StringFormat
in the PART_DateTimeTextBox
contains the value to update.
01-29-2021 08:14 AM
Hi Paul,
The Style works perfectly! However, I noticed another issue. For some reason the time in the drop down box shows one more hour than in the text field. If you look at the attached image the time in the textfield is 18:10, whereas the dropdown shows 19:10. Do you know why? This seems to be the same if I drop the Style also.
01-29-2021 10:43 AM
Looking at your original screenshot, I see the issue there was between "00.00" and "2:00" — a two-hour time difference there. This leads me to suspect a time zone issue (e.g. displaying as UTC in some places, and Local elsewhere).
I believe the popup always tries to display the Local time (which was a choice to match the user’s calendar settings, to make picking a specific date easier). Possible things to check:
Value
set with a time that has an Unspecified Kind
? (This may cause the value to get “re-interpreted” when it is displayed in different areas.)DisplayKind
property set to UTC? (This would “conflict” with the popup calendar design choice to use Local.)If it is a Local vs. UTC issue, you could use a converter instead of a format string in the binding you customized.
01-30-2021 05:57 AM
Hi Paul,
You are correct this is definitely a UTC problem. If I set windows time zone to UTZ+0 all works fine. If I set the DisplayKind to local they will match, but then the displayed value will be the control value compensated by the time zone. This means if I set the control value to 10:00, both my textbox and dropdown menu will show 11:00 (I am UTC+1). Do you have an example of how to change the format string to a converter in the Style?
02-01-2021 11:15 AM
When you say "set the control value to 10:00", how exactly are you setting it? E.g. in code with control.Value = new DateTime( 1, 1, 1, 10, 00, 00 )
? That would leave the Kind
as Unspecified
, and the control would have to guess at the appropriate interpretation, which could cause mismatches. Using SpecifyKind
may work, if that is the problem.
For the converter approach, here is an example value converter to display time as UTC:
public class DisplayUtcTimeConverter : IValueConverter {
public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) {
string format = parameter.ToString( );
var time = (DateTime)value;
string formattedValue = time.ToUniversalTime( ).ToString( format, culture );
return formattedValue;
}
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) {
string formattedValue = value.ToString( );
var parsedTime = DateTime.Parse( formattedValue, culture );
var time = DateTime.SpecifyKind( parsedTime, DateTimeKind.Utc );
return time;
}
}
And how you would add it to the control template:
...
<Grid.Resources>
<local:DisplayUtcTimeConverter x:Key="DisplayTimeConverter" />
</Grid.Resources>
...
<TextBox x:Name="PART_DateTimeTextBox"
Grid.Column="1"
Margin="3,0"
Padding="1,0"
Text="{Binding CurrentDateTime, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, Converter={StaticResource DisplayTimeConverter}, ConverterParameter='h:mm:ss.FFF tt
MM/dd/yyyy'}"
TextAlignment="Right"
TextWrapping="Wrap" />
...
02-02-2021 05:50 AM
Hi,
Have tried two approaches for setting the control value, with equal results. One is that is set it directly in xaml, i.e. Value="10:00". The other is that I create a binding which return a DateTime similar to what you describe. But you are correct, if I use SpecifyKind on the DateTime and set it to local this works! Thanks!