我是编码的新手,并决定从C#开始。我决定编写一个简单的控制台程序来检测按键,如果只按下Enter,它将显示数字。问题是你只需按住键即可继续显示数字。我应该将什么添加到我的代码中,以便程序只检测 SINGLE 按下并忽略用户 HOLDING 密钥?
(我没有找到关于 CONSOLE C#
此问题的任何内容,仅针对表单一。在此论坛上或在Web上都没有。
提前致谢
static void Main(string[] args)
{
Console.WriteLine("Press Enter to play!");
int num = 0;
void WaitForKey(ConsoleKey key)
{
while (Console.ReadKey(true).Key != key)
{ }
}
for (int i = 0; i < 10; i++)
{
WaitForKey(ConsoleKey.Enter);
Console.Write("{0} ", num);
num++;
}
}
答案 0 :(得分:1)
如果您的任务是计算键入/持有键的更改量,您只需记住最后一个键即可完成
var lastChar = char.MaxValue;
var index = 0;
do
{
var x = Console.ReadKey();
if (lastChar != x.KeyChar)
{
lastChar = x.KeyChar;
Console.WriteLine(++index);
}
} while (index < 10);
如果你需要定义单个密钥,你可以使用StopWatch
类检查从之前的密钥到来的时间(在示例300中仅用于测试,我建议深入研究它是否适合你的目标)
var sw = Stopwatch.StartNew();
do
{
var x = Console.ReadKey();
if (sw.ElapsedMilliseconds > 300)
{
Console.WriteLine(++index);
}
sw.Restart();
} while (index < 10);
或两种方式结合
答案 1 :(得分:0)
您是否尝试在num ++之后的循环中添加方法keyRelease: WaitForKeyRelease(ConsoleKey.Enter);
在你的方法中:while(Console.ReadKey(true).Key == key)
你等到按下的键没有进入所以它就像一个键释放。
答案 2 :(得分:0)
您可以通过执行以下操作来检查是否输入了“输入”:
`
string input = Console.ReadLine();
if (input == "") {
//do stuff
}
`
答案 3 :(得分:0)
是的,你不能在这里使用ReadKey
。我建议使用ReadConsoleInput WinApi函数。您可以为此目的编写包装类,例如:
internal class KeyboardInput
{
private readonly short _exitKey;
private readonly uint[] _keyStates = new uint[short.MaxValue];
public KeyboardInput(ConsoleKey exitKey)
{
_exitKey = (short) exitKey;
// subscribe with empty delegates to prevent null reference check before call
OnKeyDown += delegate { };
OnKeyUp += delegate { };
}
public event Action<char, short> OnKeyDown;
public event Action<char, short> OnKeyUp;
public void Run()
{
var exitKeyPressed = false;
var nRead = 0;
var records = new INPUT_RECORD[10];
var handle = GetStdHandle(STD_INPUT_HANDLE);
while (!exitKeyPressed)
{
ReadConsoleInputW(handle, records, records.Length, ref nRead);
for (var i = 0; i < nRead; i++)
{
// process only Key events
if (records[i].EventType != KEY_EVENT) continue;
// process key state
ProcessKey(records[i].KeyEvent.wVirtualKeyCode, records[i].KeyEvent.bKeyDown,
records[i].KeyEvent.UnicodeChar);
// check for exit key press
if ((exitKeyPressed = records[i].KeyEvent.wVirtualKeyCode == _exitKey) == true) break;
}
}
}
private void ProcessKey(short virtualKeyCode, uint keyState, char key)
{
if (_keyStates[virtualKeyCode] != keyState)
if (keyState == 1) OnKeyDown(key, virtualKeyCode);
else OnKeyUp(key, virtualKeyCode);
_keyStates[virtualKeyCode] = keyState;
}
#region Native methods
private const short KEY_EVENT = 0x0001;
private const int STD_INPUT_HANDLE = -10;
[DllImport("Kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("Kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool ReadConsoleInputW(IntPtr hConsoleInput, [Out] INPUT_RECORD[] lpBuffer, int nLength,
ref int lpNumberOfEventsRead);
[StructLayout(LayoutKind.Explicit)]
private struct INPUT_RECORD
{
[FieldOffset(0)] public readonly short EventType;
//union {
[FieldOffset(4)] public KEY_EVENT_RECORD KeyEvent;
//[FieldOffset(4)]
//public MOUSE_EVENT_RECORD MouseEvent;
//[FieldOffset(4)]
//public WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
//[FieldOffset(4)]
//public MENU_EVENT_RECORD MenuEvent;
//[FieldOffset(4)]
//public FOCUS_EVENT_RECORD FocusEvent;
}
[StructLayout(LayoutKind.Sequential)]
private struct KEY_EVENT_RECORD
{
public readonly uint bKeyDown;
public readonly short wRepeatCount;
public readonly short wVirtualKeyCode;
public readonly short wVirtualScanCode;
public readonly char UnicodeChar;
public readonly int dwControlKeyState;
}
#endregion
}
使用示例:
internal class Program
{
private static void Main(string[] args)
{
var kbInput = new KeyboardInput(ConsoleKey.Escape);
kbInput.OnKeyDown += OnKeyDown;
kbInput.OnKeyUp += OnKeyUp;
kbInput.Run();
}
private static void OnKeyDown(char key, short code)
{
Console.WriteLine($"Key pressed: {key} (virtual code: 0x{code:X})");
}
private static void OnKeyUp(char key, short code)
{
Console.WriteLine($"Key released: {key} (virtual code: 0x{code:X})");
}
}