MainWindow.xaml and add the main interface:
				
					
    
         
    
        
            
            
                
                    
                    
                    
                    
                    
                    
                 
             
            
            
                
                     
                
                     
                
                
                     
                
                     
                
                     
                 
         
     
 
			
		MainWindow.xaml.cs
				
					using System;
using System.IO;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using WebSocketSharp;
using Newtonsoft.Json.Linq;
using System.Globalization;
using System.Windows.Threading;
namespace CryptoWidgetWPF
{
    /// 
    /// Interaction logic for MainWindow.xaml
    ///  
    public partial class MainWindow : Window
    {
        private WebSocket _webSocket;
        private readonly string logFilePath = "WebSocketErrors.log"; // Path to the log file
        public MainWindow()
        {
            InitializeComponent();
            StartWebSocket();
            // Set the initial time value
            dateTimeTextBlock.Text = DateTime.Now.ToString("dd.MM.yyyy HH:mm");
            // Start a timer to update the time every second
            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(1);
            timer.Tick += (sender, args) =>
            {
                dateTimeTextBlock.Text = DateTime.Now.ToString("dd.MM.yyyy HH:mm");
            };
            timer.Start();
        }
        private void StartWebSocket()
        {
            _webSocket = new WebSocket("wss://stream.binance.com:9443/ws/!ticker@arr");
            _webSocket.OnMessage += (sender, e) =>
            {
                try
                {
                    var json = JArray.Parse(e.Data);
                    foreach (var ticker in json)
                    {
                        string symbol = ticker["s"].ToString();
                        // Only process specific symbols
                        if (symbol == "BTCUSDT" || symbol == "ETHUSDT" || symbol == "LTCUSDT")
                        {
                            if (Double.TryParse(ticker["c"].ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out double price) &&
                                Double.TryParse(ticker["P"].ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out double priceChangePercent))
                            {
                                // Format the price and percentage
                                string formattedPrice = price.ToString("#,##0.00", CultureInfo.InvariantCulture);
                                string formattedPercent = priceChangePercent.ToString("0.00", CultureInfo.InvariantCulture);
                                Dispatcher.Invoke(() =>
                                {
                                    switch (symbol)
                                    {
                                        case "BTCUSDT":
                                            btcPrice.Text = $"{formattedPrice}";
                                            btcChange.Text = $"{formattedPercent}%";
                                            btcChange.Foreground = priceChangePercent >= 0 ? Brushes.LimeGreen : Brushes.Red;
                                            break;
                                        case "ETHUSDT":
                                            ethPrice.Text = $"{formattedPrice}";
                                            ethChange.Text = $"{formattedPercent}%";
                                            ethChange.Foreground = priceChangePercent >= 0 ? Brushes.LimeGreen : Brushes.Red;
                                            break;
                                        case "LTCUSDT":
                                            ltcPrice.Text = $"{formattedPrice}";
                                            ltcChange.Text = $"{formattedPercent}%";
                                            ltcChange.Foreground = priceChangePercent >= 0 ? Brushes.LimeGreen : Brushes.Red;
                                            break;
                                    }
                                });
                            }
                            else
                            {
                                LogError($"Failed to parse price or priceChangePercent for symbol: {symbol}. Data received: {ticker.ToString()}");
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogError("Exception during OnMessage: " + ex.ToString());
                }
            };
            _webSocket.OnError += (sender, e) =>
            {
                LogError("WebSocket Error: " + e.Message);
            };
            _webSocket.OnClose += (sender, e) =>
            {
                LogError("WebSocket Closed: " + e.Reason);
                ReconnectWebSocket();
            };
            _webSocket.Connect();
        }
        private void ReconnectWebSocket()
        {
            if (_webSocket != null)
            {
                _webSocket.Close();
                _webSocket = null;
            }
            StartWebSocket();
        }
        private void LogError(string message)
        {
            try
            {
                using (StreamWriter writer = new StreamWriter(logFilePath, true))
                {
                    writer.WriteLine($"{DateTime.Now}: {message}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed to log error: " + ex.Message);
            }
        }
        private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2)
            {
                ToggleMaximizeRestore();
            }
            else
            {
                DragMove();
            }
        }
        private void Minimize_Click(object sender, RoutedEventArgs e)
        {
            WindowState = WindowState.Minimized;
        }
        private void MaximizeRestore_Click(object sender, RoutedEventArgs e)
        {
            ToggleMaximizeRestore();
        }
        private void Close_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }
        private void ToggleMaximizeRestore()
        {
            if (WindowState == WindowState.Maximized)
            {
                WindowState = WindowState.Normal;
            }
            else
            {
                WindowState = WindowState.Maximized;
            }
        }
    }
}
 
				
			
		