Resolved How do I update a property every 5 seconds following mvvm pattern using c# and .Net 4.x?

BoomBa

Member
Joined
Dec 24, 2022
Messages
8
Programming Experience
Beginner
I have a property defined in my viewmodel which is supposed to check if todays internet date is same as the system date and store it in the property as some string so that I can bind it to a textblock text or a label content.
But this check must run every 5 second as long as the app is open, that means the value of the property can change and it should reflect on the view accordingly.
How can I do this following mvvm pattern and using .Net 4.x?

I've done

C#:
    public class BaseVM : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
   
    }

    public class VM : BaseVM
    {
        private static System.Timers.Timer chkDate;
       
        public string msg {get;set;}
       
        public VM()
        {
            chkDate = new System.Timers.Timer();
           
            chkDate.Interval = 5000; // every five seconds
           
            chkDate.Elapsed += VerifyDate;
           
            chkDate.AutoReset = true;
           
            chkDate.Enabled = true;
        }
       
       
        public void VerifyDate(Object source, System.Timers.ElapsedEventArgs e)
        {
            if (IsInternetAvailable())
            {
                if (DateTime.Today.ToString("dd-MMM-yyyy") == GetInternetTime().ToString("dd-MMM-yyyy"))
                {
                    msg="Machine date verified!";
                }
               
                else
                    msg="Machine date is not correct!";
            }
           
            else
               
            {
                msg="Machine date cannot be verified! Check internet connectivity !!!";
            }
           
            OnPropertyChanged("msg");
        }
    }

Then in the label : <Label Content="{Binding msg}" Foreground="{Binding msg, Converter={StaticResource TextToColorConverter}}" ... />
I've also added an IValueConverter to convert the color of the text depending of whether msg is equal to a certain text or not:

C#:
    public class TextToColorConverter : IValueConverter
    {
        public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string str = value as string;
            if (value == null || str=="Machine date verified!")
                return new SolidColorBrush(Colors.LightGreen);

            else
                return new SolidColorBrush(Colors.Red);
        }

        public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return null;
        }

    }

But it is not working as intended, initially the value changes like if I change the system date or disconnect internet the property updates but after that I make the system date correct or activate internet the property does not update.

Can someone help?
 
Thanks. I got the below code from a stackoverflow answer and it seems to work for now

C#:
        public static DateTime GetNetworkTime()
        {
            //default Windows time server
            const string ntpServer = "time.windows.com";

            // NTP message size - 16 bytes of the digest (RFC 2030)
            var ntpData = new byte[48];

            //Setting the Leap Indicator, Version Number and Mode values
            ntpData[0] = 0x1B; //LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode)

            var addresses = Dns.GetHostEntry(ntpServer).AddressList;

            //The UDP port number assigned to NTP is 123
            var ipEndPoint = new IPEndPoint(addresses[0], 123);
            //NTP uses UDP

            using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
            {
                socket.Connect(ipEndPoint);

                //Stops code hang if NTP is blocked
                socket.ReceiveTimeout = 3000;

                socket.Send(ntpData);
                socket.Receive(ntpData);
                socket.Close();
            }

            //Offset to get to the "Transmit Timestamp" field (time at which the reply
            //departed the server for the client, in 64-bit timestamp format."
            const byte serverReplyTime = 40;

            //Get the seconds part
            ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);

            //Get the seconds fraction
            ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4);

            //Convert From big-endian to little-endian
            intPart = SwapEndianness(intPart);
            fractPart = SwapEndianness(fractPart);

            var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);

            //**UTC** time
            var networkDateTime = (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds((long)milliseconds);

            return networkDateTime.ToLocalTime();
        }

        static uint SwapEndianness(ulong x)
        {
            return (uint)(((x & 0x000000ff) << 24) +
                           ((x & 0x0000ff00) << 8) +
                           ((x & 0x00ff0000) >> 8) +
                           ((x & 0xff000000) >> 24));
        }
 
Hi, @Skydiver

Does my IsInternetAvailable() method require some changes to be less error prone ? What other ways to check for active internet connection, apart from ping obviously ?
 
Do the same kind of StackOverflow search you did like you did for how to query an NNTP server. There's several discussions about how to do that check, to try to take into account the location of the user where Google maybe blocked.
 
Back
Top Bottom