C# arrow key input for a console app

前端 未结 5 1218
一生所求
一生所求 2020-11-28 14:29

I have a simple console app written in C#. I want to be able to detect arrow key presses, so I can allow the user to steer. How do I detect keydown/keyup events with a con

5条回答
  •  萌比男神i
    2020-11-28 14:53

    I have the same issue that you and I found, here, an interesting post using tasks. The original post can be found here: C# Console Application - How do I always read input from the console?

    I have to emulate a PWM output through a Raspberry GPIO (using mono C#) to test a LCD backlight. With two simple keys I wanted to change the duty cycle (up/down) and an extra key to stop the program.

    I tried this (variables):

    static ConsoleKeyInfo key = new ConsoleKeyInfo();
    static int counter = 0;
    static int duty = 5; // Starts in 50%
    

    Main program:

    static void Main(string[] args)
    {
    // cancellation by keyboard string
        CancellationTokenSource cts = new CancellationTokenSource();
        // thread that listens for keyboard input
        var kbTask = Task.Run(() =>
        {
            while (true)
            {
                key = Console.ReadKey(true);
                if (key.KeyChar == 'x' || key.KeyChar == 'X')
                {
                    cts.Cancel();
                    break;
                }
                else if (key.KeyChar == 'W' || key.KeyChar == 'w')
                {
                    if (duty < 10)
                        duty++;
                    //Console.WriteLine("\tIncrementa Ciclo");
                    //mainAppState = StateMachineMainApp.State.TIMER;
                    //break;
                }
                else if (key.KeyChar == 'S' || key.KeyChar == 's')
                {
                    if (duty > 0)
                        duty--;
                    //Console.WriteLine("\tDecrementa Ciclo");
                    //mainAppState = StateMachineMainApp.State.TIMER;
                    // break;
                }
            }
        });
    
        // thread that performs main work
        Task.Run(() => DoWork(), cts.Token);
    
        string OsVersion = Environment.OSVersion.ToString();
        Console.WriteLine("Sistema operativo: {0}", OsVersion);
        Console.WriteLine("Menú de Progama:");
        Console.WriteLine(" W. Aumentar ciclo útil");
        Console.WriteLine(" S. Disminuir ciclo útil");
        Console.WriteLine(" X. Salir del programa");
    
        Console.WriteLine();
        // keep Console running until cancellation token is invoked
        kbTask.Wait();
    }
    
    static void DoWork()
    {
        while (true)
        {
            Thread.Sleep(50);
            if (counter < 10)
            {
                if (counter < duty)
                    Console.Write("─");
                    //Console.WriteLine(counter + " - ON");
                else
                    Console.Write("_");
                    //Console.WriteLine(counter + " - OFF");
                counter++;
            }
            else
            {
                counter = 0;
            }
        }
    }
    

    When it's needed to increment the duty cycle, pressing 'W' key makes that the main task changes the duty cycle variable (duty); the same thing with 'S' key to decrement. The program finishes when 'X' key is pressed.

提交回复
热议问题