Консоль и SetCursorPosition C#

232
24 декабря 2017, 06:28

Доброго времени суток. Делаю лабораторную работу по программированию (вопрос не о методе решения) и возникла проблема с консолью.

Суть задачи в том, чтобы сформировать таблицу с данными. Программу нужно научить добавлять и удалять оттуда значения (и другое). Вот как выглядит содержимое в консоли: Код вывода всех окошек, думаю, показывать нет необходимости. Лишь скажу, что после того, как была нажата кнопочка "2" на клавиатуре, выводится второе окошко "Добавление записи", выводится его содержимое, а после курсор устанавливается на нужную позицию (справа от "Наименования").

Итак, проблема первая: по какой-то причине, на какую бы из стрелок я не нажимал, курсор бежит вправо.

Проблема вторая: при попытке усмирить его при помощи Console.SetCursorPosition под новой позицией курсора стирается находящийся там символ.

Для обработки нажатий я использую следующий код:

_cell[0] = new StringBuilder(' ');
_cell[1] = new StringBuilder(' ');
_cell[2] = new StringBuilder(' ');
_cell[3] = new StringBuilder(' ');
int currentPos = 0;
bool exit = false;
ConsoleKeyInfo ck;
do
{
    ck = Console.ReadKey();
    if (char.IsLetter(ck.KeyChar))
    {
        if (currentPos == 2 || currentPos == 3)
        {
            if (char.IsDigit(ck.KeyChar)) _cell[currentPos].Append(ck.KeyChar);
        }
        else
        {
            _cell[currentPos].Append(ck.KeyChar);
        }
    }
    else
    {   
        switch (ck.Key)
        {
             case ConsoleKey.Enter:
                 //*тут будет сохранение*
                 exit = true;
                 break;
             case ConsoleKey.Escape:
                 exit = true;
                 break;
             case ConsoleKey.UpArrow:
                 if (currentPos == 0) currentPos = (Record.ColumnCount - 1);
                 else currentPos--;
                 Console.CursorTop = startY + currentPos;
                 Console.CursorLeft = startX + Record.ColumnNames[currentPos].Length + _cell[currentPos].Length + 2;
                 break;
             case ConsoleKey.DownArrow:
                 if (currentPos == Record.ColumnCount - 1) currentPos = 0;                        else currentPos++;
                 Console.CursorTop = startY + currentPos;
                 Console.CursorLeft = startX + Record.ColumnNames[currentPos].Length + _cell[currentPos].Length + 2;
                 break;
             case ConsoleKey.LeftArrow:            
                 Console.CursorLeft -= 2;
                 if (Console.CursorLeft < startX + Record.ColumnNames[currentPos].Length + 2) Console.CursorLeft +=  1;
                 break;
             case ConsoleKey.RightArrow:
                 if (Console.CursorLeft > startX + +Record.ColumnNames[currentPos].Length + (_cell[currentPos].Length))
                 Console.CursorLeft -= 1;
                 break;
        }
    }
} while (!exit);

Немного заметок:

currentPos - переменная, отвечающая за строку, на которой находится юзер (то бишь между теми четырьмя строками)

startX, startY - координаты буквы "Н" в слове "Наименование" по отношению к окну (не знаю как выразиться грамотнее). Место, откуда начинается писанина в нижнем окне.

Record.ColumnNames[] - массив с названиями колонок ("Наименование" и остальное).

Как решить проблему (вторую. Первую - просто хочется понять почему так)? Вариант с обыкновенным ReadLine() не хочется реализовывать (хотя тогда все в разы проще было бы), ибо так нельзя будет отловить нажатие стрелок и Escape.

Answer 1

Console.ReadKey() читает клавишу с выводом её на экран. Соответственно и символ стрелки выводится на экран тоже. (Возможно, он в вашем шрифте пустой.) Вне зависимости от направления стрелки этот символ выводится в текущую позицию курсора, и курсор сдвигается вправо. При этом он, разумеется, затирает символ, находящийся в новой позиции курсора.

Думаю, вам стоит читать клавишу без отображения:

Console.ReadKey(intercept: true)

и выводить только то, что нужно (цифры/буквы/...).

READ ALSO
Определить следующие 6 месяцев

Определить следующие 6 месяцев

Как можно при помощи momentjs определить следующие 6 месяцев? Например, сегодня 12 месяц по счёту и я бы хотел на выходе получить массив:

286
отсортировать буквы и цифры javascript

отсортировать буквы и цифры javascript

дана строка из букв и цифрнадо отсортировать что бы буквы ушли вперед, а цифры назад

195
JSON в массив объектов

JSON в массив объектов

Есть JSON объект

335
Vue: не срабатывает v-on:click

Vue: не срабатывает v-on:click

Не срабатывает скрипт, подключаю Vue через cdn (v 25

240