The only way to show current time updating regularly I found is to use timer. Of course, I can implement INotifyPropertyChanged
and some special property to be used on UI but this implementation AFAIK also needs Timer
. For example like here. Are there any better way to display current time?
Edit
To clarify: are there any declarative way to make it work in real time without timer using XAML syntax like this?
<Label Content="{x:Static s:DateTime.Now}" ContentStringFormat="G" />
Nothing stops me from using timer here. I just want to know if there are more elegant and compact way of implementing this.
WPF is a static markup language. As far as I am aware there is not a mechanism available in pure XAML to provide the functionally you are looking for.
If you want to avoid using a timer directly you can abstract it away using Tasks.
MainWindow XAML:
<Window x:Class="AsyncTimer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AsyncTimer"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Label Content="{Binding CurrentTime}"></Label>
</Grid>
</Window>
Code behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new CurrentTimeViewModel();
}
}
public class CurrentTimeViewModel : INotifyPropertyChanged
{
private string _currentTime;
public CurrentTimeViewModel()
{
UpdateTime();
}
private void UpdateTime()
{
Task.Run(() =>
{
CurrentTime = DateTime.Now.ToString("G");
Task.Delay(1000);
UpdateTime();
});
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string CurrentTime
{
get { return _currentTime; }
set { _currentTime = value; OnPropertyChanged(); }
}
}
This is probably one of the more succinct and certainly as "Modern" WPF you are going to get.
Using Task.Delay can produce an high CPU usage!
In the XAML code write this:
<Label Name="LiveTimeLabel" Content="%TIME%" HorizontalAlignment="Left" Margin="557,248,0,0" VerticalAlignment="Top" Height="55" Width="186" FontSize="36" FontWeight="Bold" Foreground="Red" />
Next in the xaml.cs write this:
[...]
public MainWindow()
{
InitializeComponent();
DispatcherTimer LiveTime = new DispatcherTimer();
LiveTime.Interval = TimeSpan.FromSeconds(1);
LiveTime.Tick += timer_Tick;
LiveTime.Start();
}
void timer_Tick(object sender, EventArgs e)
{
LiveTimeLabel.Content = DateTime.Now.ToString("HH:mm:ss");
}
[...]