Show current time WPF

后端 未结 3 586
醉话见心
醉话见心 2021-01-07 06:45

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

相关标签:
3条回答
  • 2021-01-07 06:50

    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 async void UpdateTime()
        {
            CurrentTime = DateTime.Now.ToString("G");
            await 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.

    0 讨论(0)
  • 2021-01-07 06:57

    Here is a little code sample that works without a timer:

    public DateTime CurrentTime
    {
        get => DateTime.Now;
    }
    
    public CurrentViewModelTime(object sender, RoutedEventArgs e)
    {
        _ = Update(); // calling an async function we do not want to await
    }
    
    private async Task Update()
    {
        while (true)
        {
            await Task.Delay(100);
            OnPropertyChanged(nameof(CurrentTime)));
        }
    }
    

    Of course, this Update() function never returns, but it does its loop on a threadpool thread and does not even block any thread for long.

    You can perfectly also implement this in the window directly without a viewmodel.

    0 讨论(0)
  • 2021-01-07 07:00

    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");
    }
    [...]
    
    0 讨论(0)
提交回复
热议问题