首页 > 解决方案 > 在继续执行代码之前等待面板上的 KeyDown

问题描述

我目前正在构建一个应用程序,其中用户有一个需要触发的项目列表。操作员使用快捷方式(“添加”按钮)触发此操作。现在大多数项目只包含一个正在执行的操作,但是,有些项目包含多个步骤。这些步骤需要由操作员控制。

所以即使是一个被触发的项目,项目内部的步骤也需要通过快捷方式来控制。

private void function triggerItem()
{
   // Perform Step 1
   // PAUSE (AWAIT KEYPRESS)
   // Perform Step 2
   // PAUSE (AWAIT KEYPRESS)
   // Perform Step 3
}

所以现在为了测试它,我刚刚使用了一个消息框在不同步骤之间“暂停”,但我想让它更清楚一点。因此,我创建了一个带有 keydown 事件的面板,该面板可以捕获按下的“添加”按钮以使功能继续。

但我认为我需要一种任务,我可以在继续其他操作之前等待结果。除了我看不到如何等待面板中的 keydown 事件以将值返回给 await 函数。

我怎么能做到这一点?

private void showWarning()
{
    // SHOW THE WARNING
    panWarning.Show();

    // ENSURE THE FOCUS IS SET TO THE PANEL TO CAPTURE THE KEY DOWN EVENT
    panWarning.Focus();

    // AWAIT THE KEYPRESS TO CONTINUE THE FUNCTION
}

    private void panWarning_KeyDown(object sender, KeyEventArgs e)
    {
        // CHECK WHICH BUTTON WAS PRESSED
        switch (e.KeyCode)
        {
            case Keys.Add:
                // CONTINUE
                break;

            case Keys.Escape:
                // ABORT
                break;
        }    
    }

有什么建议么?谢谢你。

标签: c#winformsasync-awaittask

解决方案


您可以使用TaskCompletionSource来等待任何事情。要解决您的问题,请创建一个并将其结果设置在事件处理程序中。

像这样的方法可以做到这一点:

public async Task WaitForKey(Control control)
{
    var tcs = new TaskCompletionSource<bool>();

    void LocalHandler(object s, EventArgs a)
    {
        tcs.SetResult(true);
    }
    control.KeyDown += LocalHandler;
    await tcs.Task;
    control.KeyDown -= LocalHandler;
}

你会这样称呼它:

private async Task TriggerItem()
{
    // Perform Step 1
    await WaitForKey(this);
    // Perform Step 2
    await WaitForKey(this);
    // Perform Step 3
}

请注意,如果您正在等待表单本身的按键,您可能需要将KeyPreview设置为 true。


推荐阅读