Murthy
Murthy

Reputation: 185

Unable to see the Date time text on the WPF application screen

I am trying to write a simple MVVM application. The expectation of this sample is to show up the time on the screen. The xaml designer showed the time once in the designer enter image description here

but when I run the app, I dont see the time on the screen at all. Could you please help me find what the issue is? I am attaching the code here.

MainWindow.xaml

    <Window x:Class="WPFDigitalClock.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:WPFDigitalClock"        
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:ClockVM/>
    </Window.DataContext>
    <Grid>
        <StackPanel>
            <TextBlock Foreground="White" Background="Black" FontSize="30" TextAlignment="Center" Text="{Binding Path=DisplayTime}"/>
        </StackPanel>
    </Grid>
</Window>

MainWindow.xaml.cs

using System.Windows;

namespace WPFDigitalClock
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();            
        }
    }
}

ClockVM.cs

using System;
using System.ComponentModel;
using System.Windows.Threading;

namespace WPFDigitalClock
{
    class ClockVM : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private ClockModel clockModel;       

        DispatcherTimer Timer = new DispatcherTimer();
        public string DisplayTime { get; set; }

        public ClockVM()
        {
            clockModel = new ClockModel();
            DisplayTime = "";
            Timer.Interval = new TimeSpan(0, 0, 1);
            Timer.Tick += new EventHandler(Timer_Click);
            Timer.Start();

        }

        private void Timer_Click(object sender, EventArgs e)
        {
            DisplayTime = clockModel.Hour + ":" + clockModel.Minute + ":" + clockModel.Second;
            if (PropertyChanged != null)
            {
                PropertyChanged(sender, new PropertyChangedEventArgs("DisplayTime"));
            }
        }
    }
}

ClockModel.cs

using System;

namespace WPFDigitalClock
{
    class ClockModel
    {
        public string Hour
        {
            get { return DateTime.Now.Hour.ToString(); }            
        }

        public string Minute
        {
            get { return DateTime.Now.Minute.ToString(); }
        }

        public string Second
        {
            get { return DateTime.Now.Second.ToString(); }
        }
    }
}

Upvotes: 2

Views: 56

Answers (2)

StepUp
StepUp

Reputation: 38134

Cannot reproduce your error. I've just added a counter and it updates perfectly.

int counter = 0;
private void Timer_Tick(object sender, EventArgs e)
{
   DisplayTime = clockModel.Hour + ":" + clockModel.Minute + ":" + 
   clockModel.Second + " Counter:" + counter++.ToString();          
   OnPropertyChanged("DisplayTime");            
 }


 public event PropertyChangedEventHandler PropertyChanged;
 protected virtual void OnPropertyChanged(string propertyName)
 {
     var handler = PropertyChanged;
     if (handler != null)
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
 }

My xaml is:

<Window x:Class="DataGridSelectedItemsWpfApplication.MainWindow"
        <!--The code omitted for the brevity-->
        xmlns:vm="clr-namespace:DataGridSelectedItemsWpfApplication.ViewModel"
        Title="MainWindow" WindowStartupLocation="CenterScreen" Height="350" Width="525">
    <Window.DataContext>
        <vm:MyViewModel/>
    </Window.DataContext>
    <Grid>
        <TextBlock Text="{Binding DisplayTime}"/>        
    </Grid>
</Window>

The model is the same like your model.

This works like this:

enter image description here

Update:

As @KyloRen says correctly about your mistake. Just change from PropertyChanged(SENDER, new PropertyChangedEventArgs(propertyName)); TO PropertyChanged(this, new PropertyChangedEventArgs(propertyName));. It means that you raise an event from ClockVM.

Upvotes: 1

Kylo Ren
Kylo Ren

Reputation: 8823

Problem is with how you have Raised the change of property DisplayTime. use belowDispatcherTimer.Tick handler as:

 private void Timer_Click(object sender, EventArgs e)
    {
        DisplayTime = clockModel.Hour + ":" + clockModel.Minute + ":" + clockModel.Second;
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs("DisplayTime"));
        }
    }

You have passed the sender object as argument in PropertyChanged method. It expect owner class of Property DisplayTime in sender argument.

Upvotes: 3

Related Questions