Страницы

Поиск по вопросам

воскресенье, 7 июля 2019 г.

Консоль и SetCursorPosition C#

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


Ответ

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

Комментариев нет:

Отправить комментарий