Загрузка данных


<Window x:Class="KeyboardTrainer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Клавиатурный тренажёр" Height="550" Width="1000"
        WindowStartupLocation="CenterScreen"
        KeyDown="Window_KeyDown">
    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- Панель статистики -->
        <Border Grid.Row="0" Margin="5" Padding="10" Background="#F0F0F0" CornerRadius="8">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <StackPanel Grid.Column="0" Orientation="Horizontal" HorizontalAlignment="Center">
                    <TextBlock Text="Скорость: " FontSize="18" FontWeight="Bold"/>
                    <TextBlock x:Name="SpeedText" Text="0" FontSize="18" FontWeight="Bold" Foreground="Green"/>
                    <TextBlock Text=" симв/мин" FontSize="18"/>
                </StackPanel>
                <StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Center">
                    <TextBlock Text="Ошибки: " FontSize="18" FontWeight="Bold"/>
                    <TextBlock x:Name="ErrorsText" Text="0" FontSize="18" FontWeight="Bold" Foreground="Red"/>
                </StackPanel>
                <StackPanel Grid.Column="2" Orientation="Horizontal">
                    <Button x:Name="StartButton" Content="Start" Width="80" Margin="5" Click="StartButton_Click"/>
                    <Button x:Name="StopButton" Content="Stop" Width="80" Margin="5" Click="StopButton_Click" IsEnabled="False"/>
                    <ComboBox x:Name="DifficultyCombo" Width="120" Margin="5" SelectedIndex="1">
                        <ComboBoxItem Content="Лёгкий (a-z)"/>
                        <ComboBoxItem Content="Средний (+Shift)"/>
                        <ComboBoxItem Content="Сложный (+цифры/знаки)"/>
                    </ComboBox>
                </StackPanel>
            </Grid>
        </Border>

        <!-- Строка для ввода -->
        <Border Grid.Row="1" Margin="5" Padding="10" Background="#FFFACD" CornerRadius="8">
            <StackPanel>
                <TextBlock Text="Введите текст:" FontWeight="Bold" Margin="0,0,0,5"/>
                <TextBlock x:Name="TargetTextBlock" Text="Нажмите Start" FontSize="16" FontFamily="Courier New" FontWeight="Bold" Margin="0,0,0,10"/>
                <TextBox x:Name="InputTextBox" FontSize="16" FontFamily="Courier New" IsEnabled="False" KeyDown="InputTextBox_KeyDown"/>
            </StackPanel>
        </Border>

        <!-- Клавиатура (ряды) -->
        <StackPanel Grid.Row="2" Margin="5">
            <!-- Ряд 1 -->
            <WrapPanel Margin="0,2">
                <Button x:Name="Key_Tab" Content="Tab" Width="60" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_Q" Content="Q" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_W" Content="W" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_E" Content="E" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_R" Content="R" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_T" Content="T" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_Y" Content="Y" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_U" Content="U" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_I" Content="I" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_O" Content="O" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_P" Content="P" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_BracketOpen" Content="[" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_BracketClose" Content="]" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
            </WrapPanel>

            <!-- Ряд 2 -->
            <WrapPanel Margin="0,2">
                <Button x:Name="Key_Caps" Content="Caps" Width="75" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_A" Content="A" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_S" Content="S" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_D" Content="D" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_F" Content="F" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_G" Content="G" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_H" Content="H" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_J" Content="J" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_K" Content="K" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_L" Content="L" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_Semicolon" Content=":" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_Quote" Content="'" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_Enter" Content="Enter" Width="80" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
            </WrapPanel>

            <!-- Ряд 3 -->
            <WrapPanel Margin="0,2">
                <Button x:Name="Key_ShiftLeft" Content="Shift" Width="85" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_Z" Content="Z" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_X" Content="X" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_C" Content="C" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_V" Content="V" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_B" Content="B" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_N" Content="N" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_M" Content="M" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_Less" Content="&lt;" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_Greater" Content="&gt;" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_Question" Content="?" Width="50" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
                <Button x:Name="Key_ShiftRight" Content="Shift" Width="85" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
            </WrapPanel>

            <!-- Пробел -->
            <WrapPanel Margin="0,2" HorizontalAlignment="Center">
                <Button x:Name="Key_Space" Content="Space" Width="300" Height="50" Margin="2" Style="{StaticResource KeyButtonStyle}"/>
            </WrapPanel>
        </StackPanel>
    </Grid>
</Window>








<Application x:Class="KeyboardTrainer.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <Style x:Key="KeyButtonStyle" TargetType="Button">
            <Setter Property="FontWeight" Value="Bold"/>
            <Setter Property="FontSize" Value="14"/>
            <Setter Property="Background" Value="LightGray"/>
            <Setter Property="Foreground" Value="Black"/>
            <Setter Property="BorderBrush" Value="Gray"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                CornerRadius="4">
                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="IsPressed" Value="True">
                    <Setter Property="Background" Value="Yellow"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Application.Resources>
</Application>







using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Threading;
using System.Windows.Threading;

namespace KeyboardTrainer
{
    public partial class MainWindow : Window
    {
        private bool isTrainingActive = false;
        private string targetText = "";
        private int currentPosition = 0;
        private int errorCount = 0;
        private DateTime sessionStartTime;
        private DispatcherTimer timer;

        private Dictionary<Key, Button> keyMap;

        public MainWindow()
        {
            InitializeComponent();
            InitializeKeyMap();
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(0.5);
            timer.Tick += Timer_Tick;
        }

        private void InitializeKeyMap()
        {
            keyMap = new Dictionary<Key, Button>
            {
                { Key.Q, Key_Q }, { Key.W, Key_W }, { Key.E, Key_E }, { Key.R, Key_R },
                { Key.T, Key_T }, { Key.Y, Key_Y }, { Key.U, Key_U }, { Key.I, Key_I },
                { Key.O, Key_O }, { Key.P, Key_P }, { Key.A, Key_A }, { Key.S, Key_S },
                { Key.D, Key_D }, { Key.F, Key_F }, { Key.G, Key_G }, { Key.H, Key_H },
                { Key.J, Key_J }, { Key.K, Key_K }, { Key.L, Key_L }, { Key.Z, Key_Z },
                { Key.X, Key_X }, { Key.C, Key_C }, { Key.V, Key_V }, { Key.B, Key_B },
                { Key.N, Key_N }, { Key.M, Key_M }, { Key.Space, Key_Space },
                { Key.Enter, Key_Enter }, { Key.Tab, Key_Tab },
                { Key.LeftShift, Key_ShiftLeft }, { Key.RightShift, Key_ShiftRight }
            };
        }

        private void Window_KeyDown(object sender, KeyEventArgs e)
        {
            if (!isTrainingActive) return;

            HighlightKey(e.Key, Brushes.LightGreen);
            
            if (e.Key == Key.Back)
            {
                if (currentPosition > 0)
                {
                    currentPosition--;
                    errorCount = Math.Max(0, errorCount - 1);
                    UpdateErrors();
                }
                e.Handled = true;
                return;
            }

            char pressed = GetCharFromKey(e.Key);
            if (currentPosition < targetText.Length && pressed == targetText[currentPosition])
            {
                currentPosition++;
                UpdateSpeed();
            }
            else
            {
                errorCount++;
                UpdateErrors();
            }

            if (currentPosition == targetText.Length)
            {
                StopTraining();
                MessageBox.Show("Поздравляем! Текст набран полностью.", "Отлично!");
            }
        }

        private void HighlightKey(Key key, SolidColorBrush color)
        {
            if (keyMap.ContainsKey(key))
            {
                var btn = keyMap[key];
                var original = btn.Background;
                btn.Background = color;
                var timer = new System.Timers.Timer(150);
                timer.Elapsed += (s, e) => Dispatcher.Invoke(() => btn.Background = original);
                timer.AutoReset = false;
                timer.Start();
            }
        }

        private char GetCharFromKey(Key key)
        {
            if (key == Key.Space) return ' ';
            if (key == Key.Enter) return '\n';
            string k = key.ToString();
            if (k.Length == 1) return k[0];
            return '\0';
        }

        private void UpdateSpeed()
        {
            double minutes = (DateTime.Now - sessionStartTime).TotalMinutes;
            if (minutes <= 0) minutes = 0.01;
            int speed = (int)(currentPosition / minutes);
            SpeedText.Text = speed.ToString();
        }

        private void UpdateErrors()
        {
            ErrorsText.Text = errorCount.ToString();
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            UpdateSpeed();
        }

        private void StartButton_Click(object sender, RoutedEventArgs e)
        {
            StartTraining();
        }

        private void StopButton_Click(object sender, RoutedEventArgs e)
        {
            StopTraining();
        }

        private void StartTraining()
        {
            targetText = GenerateText();
            TargetTextBlock.Text = targetText;
            currentPosition = 0;
            errorCount = 0;
            sessionStartTime = DateTime.Now;
            isTrainingActive = true;
            InputTextBox.IsEnabled = true;
            InputTextBox.Clear();
            InputTextBox.Focus();
            StartButton.IsEnabled = false;
            StopButton.IsEnabled = true;
            timer.Start();
            UpdateErrors();
            SpeedText.Text = "0";
        }

        private void StopTraining()
        {
            isTrainingActive = false;
            InputTextBox.IsEnabled = false;
            StartButton.IsEnabled = true;
            StopButton.IsEnabled = false;
            timer.Stop();
        }

        private string GenerateText()
        {
            var random = new Random();
            int length = 30;
            string chars = "";
            int level = DifficultyCombo.SelectedIndex;
            switch (level)
            {
                case 0: chars = "abcdefghijklmnopqrstuvwxyz "; break;
                case 1: chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ "; break;
                case 2: chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.?!- "; break;
            }
            return new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());
        }

        private void InputTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (!isTrainingActive) return;
            if (e.Key == Key.Back) return;

            string currentInput = InputTextBox.Text;
            if (currentInput.Length < targetText.Length && e.Key != Key.Enter)
            {
                e.Handled = true;
                char pressed = GetCharFromKey(e.Key);
                if (pressed != '\0')
                {
                    InputTextBox.AppendText(pressed.ToString());
                    Window_KeyDown(sender, e);
                }
            }
            else if (currentInput.Length >= targetText.Length)
            {
                StopTraining();
            }
        }
    }
}