DispatcherTimer in WPF -View Model or Model - MVVM

Kalpana 286 Reputation points
2022-08-23T08:50:19.003+00:00

Hi

I would like to know where should I place my dispatcher time in wpf mvvm pattern. Should I place it in View Model or the model and where should I place the INotifyPropertyChanged interface -if it's at the ViewModel, how can I trigger the timer then.. My code so far...the clock just does not tick.

I have placed the DispatcherTimer in my model class..what am I doing that's wrong

View

  <StackPanel Orientation="Horizontal" Margin="250,0,0,0">  
                    <Label Content="Date" Width="45" Height="30" Style="{StaticResource HeaderStyle}"/>  
                    <TextBox x:Name="txtboxdate" Width="100" Height="20" IsReadOnly="True" Background="#bc9d1b" Text="{Binding Path=Mch.MachineCurrentTime, StringFormat=MM/dd/yyyy, Mode=OneWay}"/>  
                    <Label Content="Time" Width="45" Height="30" Margin="40,0,0,0" Style="{StaticResource HeaderStyle}"/>  
                    <TextBox x:Name="txtboxtime" Width="100" Height="20" IsReadOnly="True" Background="#bc9d1b" Text="{Binding Path=Mch.MachineCurrentTime, StringFormat=hh:mm:ss.fff tt, Mode=OneWay}"/>  
                </StackPanel>  

ViewModel

     public class MachineViewModel : INotifyPropertyChanged  
        {  
           
            public MachineViewModel()  
            {  
                _mch = new Machine();  
              
            }  
      
            private Machine _mch;  
      
            public Machine Mch  
            {  
                get  
                {  
                    return _mch;  
                }  
                set  
                {  
                    _mch = value;  
                }  
            }  
      
            public DateTime MachineCurrentTime  
            {  
                get  
                {  
                    return _mch.MachineCurrentTime;  
                }  
                set  
                {  
                    _mch.MachineCurrentTime = value;  
                    NotifyPropertyChanged("MachineCurrentTime");  
                }  
            }  
      
      
      
            public event PropertyChangedEventHandler PropertyChanged;  
      
            // Property Change Logic    
            private void NotifyPropertyChanged(string propertyName)  
            {  
                if (PropertyChanged != null)  
                {  
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));  
                }  
            }  
           
      
            
      
        }  

Model

    public class Machine  
        {  
            public Machine()  
            {  
                DispatcherTimerSetup();  
               
            }  
      
      
            private DateTime _machineCurrentTime;  
                  
                  
            public DateTime MachineCurrentTime  
            {  
      
                get  
                {  
                    return _machineCurrentTime;  
                }  
                set  
                {  
                    _machineCurrentTime = value;  
                }  
            }  
      
            public void DispatcherTimerSetup()  
            {  
                DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();  
                dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);  
                dispatcherTimer.Interval = new TimeSpan(0, 0, 1);  
                dispatcherTimer.Start();  
            }  
      
            private void dispatcherTimer_Tick(object sender, EventArgs e)  
            {  
                // Updating the Label which displays the current second  
                _machineCurrentTime = DateTime.Now;  
      
                // Forcing the CommandManager to raise the RequerySuggested event  
                CommandManager.InvalidateRequerySuggested();  
            }  
      
      
      
      
        }  
  
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,710 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,650 questions
XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
790 questions
0 comments No comments
{count} vote

2 answers

Sort by: Most helpful
  1. Hui Liu-MSFT 47,341 Reputation points Microsoft Vendor
    2022-08-24T06:19:15.007+00:00

    For the problem of DispatcherTimer in WPF you could refer to the following code. If your Machine class doesn't matter, you can put the properties and related methods directly in the ViewModel. Then bind the properties.

    Xaml:

     <StackPanel Orientation="Horizontal" Margin="250,0,0,0">  
            <Label Content="Date" Width="45" Height="30" />  
            <TextBox x:Name="txtboxdate" Width="150" Height="20" IsReadOnly="True"  Text="{Binding Path=Mch.CurrentDate}"/>  
            <Label Content="Time" Width="45" Height="30" Margin="40,0,0,0" />  
            <TextBox x:Name="txtboxtime" Width="130" Height="20" IsReadOnly="True" Text="{Binding Path=Mch.CurrentTime}"/>  
        </StackPanel>  
    

    Codebehind:

      public partial class MainWindow : Window  
        {  
            public MainWindow()  
            {  
                InitializeComponent();  
                DataContext = new  MachineViewModel();  
            }  
        }  
        public class MachineViewModel : INotifyPropertyChanged  
        {  
            public MachineViewModel()  
            {  
                _mch = new Machine();  
      
            }  
            private Machine _mch;  
            public Machine Mch  
            {  
                get  
                {  
                    return _mch;  
                }  
                set  
                {  
                    _mch = value;  
                }  
            }  
            public event PropertyChangedEventHandler PropertyChanged;  
            private void NotifyPropertyChanged(string propertyName)  
            {  
                if (PropertyChanged != null)  
                {  
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));  
                }  
            }  
        }  
        public class Machine : INotifyPropertyChanged  
        {  
            private string _currentTime, _currentDate;  
            public Machine()  
            {  
                CurrentDateText();  
                 
                DispatcherTimerSetup();  
            }  
            public string CurrentTime  
            {  
                get { return _currentTime; }  
                set  
                {  
                    if (_currentTime != value)  
                        _currentTime = value;  
      
                    OnPropertyChanged("CurrentTime");  
                }  
            }  
      
            public string CurrentDate  
            {  
                get { return _currentDate; }  
                set  
                {  
                    if (_currentDate != value)  
                        _currentDate = value;  
      
                    OnPropertyChanged("CurrentDate");  
                }  
            }  
            private void CurrentDateText()  
            {  
                CurrentDate = DateTime.Now.ToString("MM/dd/yyyy");  
            }  
      
            private void CurrentTimeText(object sender, EventArgs e)  
            {  
                CurrentTime = DateTime.Now.ToString("HH:mm:ss");  
            }  
            private DateTime _machineCurrentTime;  
            public DateTime MachineCurrentTime  
            {  
                get  
                {  
                    return _machineCurrentTime;  
                }  
                set  
                {  
                    _machineCurrentTime = value;  
                }  
            }  
            private void DispatcherTimerSetup()  
            {  
                DispatcherTimer dispatcherTimer = new DispatcherTimer();  
                dispatcherTimer.Interval = TimeSpan.FromSeconds(1);  
                dispatcherTimer.Tick += new EventHandler(CurrentTimeText);  
                dispatcherTimer.Start();  
            }  
            public event PropertyChangedEventHandler PropertyChanged;  
            private void OnPropertyChanged(string propertyName)  
            {  
                if (PropertyChanged != null)  
                {  
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));  
                }  
            }  
        }  
    

    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

  2. Kalpana 286 Reputation points
    2022-08-25T07:46:37.067+00:00

    Thanks, I have got it working...but I have this question why can't the timer work on the field instead of the property. The field is private. Sorry, I am a beginner
    public class Machine : INotifyPropertyChanged
    {
    public Machine()
    {
    DispatcherTimerSetup();
    }
    private DateTime _mchCurrentTime;

            public DateTime MchCurrentTime  
            {  
                get  
                {  
                    return _mchCurrentTime;  
                }  
                set  
                {  
                    if(_mchCurrentTime != value)  
                    {  
                        _mchCurrentTime = value;  
                    }  
                    OnPropertyChanged("MchCurrentTime");  
                }  
            }  
      
      
      
            private void DispatcherTimerSetup()  
            {  
                DispatcherTimer dispatcherTimer = new DispatcherTimer();  
                dispatcherTimer.Interval = TimeSpan.FromSeconds(1);  
                dispatcherTimer.Tick += new EventHandler(CurrentTimeText);  
                dispatcherTimer.Start();  
            }  
      
            private void CurrentTimeText(object sender, EventArgs e)  
            {  
                _mchCurrentTime = DateTime.Now;  
            }  
      
            public event PropertyChangedEventHandler PropertyChanged;  
      
            public void OnPropertyChanged(string propertyName)  
            {  
                PropertyChangedEventHandler ph = PropertyChanged;  
                if (ph != null)  
                    ph(this, new PropertyChangedEventArgs(propertyName));  
            }  
      
        }  
    

    When I change the field to the property MchCurrentTime, the view displays the timer and it ticks, however, the timer does not tick when I use _mchCurrentTime, why is that so.