mylim
mylim

Reputation: 313

UWP C# MVVM clock example

I am trying to start by looking at a simple clock example. i am wondering how to I convert a normal clock to MVVM. Can someone help? Thanks.

private void startClock()
    {
        currentTime = DateTime.Now;
        DispatcherTimer clocktimer = new DispatcherTimer();
        clocktimer.Interval = TimeSpan.FromSeconds(1);
        clocktimer.Tick += Clocktimer_Tick;
        clocktimer.Start();
    }

    private void Clocktimer_Tick(object sender, object e)
    {
        currentTime = DateTime.Now;
        updateTimeDisplay(currentTime);
    }

    private void updateTimeDisplay(DateTime time)
    {
        Time.Text = time.ToString(@"HH\:mm");
        Sec.Text = time.ToString(@"ss");
        Date.Text = time.ToString(@"ddd  dd-MM-yyyy");
    }

Update I can't post more codes as the system flagged and unable to post.

enter image description here

Upvotes: 0

Views: 516

Answers (2)

Nico Zhu
Nico Zhu

Reputation: 32785

UWP C# MVVM clock example

You could make string property in the viewmode and bind it with your textblock in the xaml. When you update the this property, it will notify ui update.

For example:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public ViewModel()
    {
        startClock();
    }

    private DateTime _currentTime;
    private void startClock()
    {
        _currentTime = DateTime.Now;
        DispatcherTimer clocktimer = new DispatcherTimer();
        clocktimer.Interval = TimeSpan.FromSeconds(1);
        clocktimer.Tick += Clocktimer_Tick;
        clocktimer.Start();
    }

    private void Clocktimer_Tick(object sender, object e)
    {
        _currentTime = DateTime.Now;
        updateTimeDisplay(_currentTime);
    }

    private void updateTimeDisplay(DateTime time)
    {
        Time = time.ToString(@"HH:mm:ss");
    }
    public void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        // Raise the PropertyChanged event, passing the name of the property whose value has changed.
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    private string _time;
    public string Time
    {
        get
        {
            return _time;
        }
        set
        {
            _time = value;
            this.OnPropertyChanged();

        }
    }
}

Xaml code

<Page.DataContext>
    <local:ViewModel />
</Page.DataContext>
<Grid>
    <TextBlock
        x:Name="Time"
        HorizontalAlignment="Center"
        VerticalAlignment="Center"
        FontSize="25"
        Text="{Binding Time}"
        TextAlignment="Center" />
</Grid>

For detail mvvm design, please refer data binding in depth document.

Upvotes: 1

Dennis
Dennis

Reputation: 37780

View model will be something like this:


public class ClockViewModel : ViewModelBase
{
    public ClockViewModel()
    {
        var _ = UpdateCurrentDateTimeAsync();
    }

    public DateTime? CurrentDateTime { get; private set; }

    private async Task UpdateCurrentDateTimeAsync()
    {
        while (true)
        {
            CurrentDateTime = DateTime.Now;
            OnPropertyChanged(nameof(CurrentDateTime));

            await Task.Delay(1000);
        }
    }
}

Just set it as the DataContext of your view and bind some visual (e.g. TextBox) to CurrentDateTime property. ViewModelBase is a very basic INotifyPropertyChanged implementation.

Upvotes: 1

Related Questions