在WPF中如何通过按键打破while循环?

4
我看到了有人解答了如何在控制台应用和WinForms应用程序中通过按键来退出while循环的问题,但不知道如何在WPF应用程序中实现。那么,你该怎么做呢?谢谢。
好的,让我们详细说明一下: 在WPF(非控制台)应用程序中,像这样的代码是行不通的。它会抛出运行时错误:
while(!Console.KeyAvailable)
{
//do work
}    
2个回答

1
您可以在MainWindowKeyDown事件中创建一个事件,并获取KeyEventArgs e来了解按下了哪个键。
private void Window_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.A)
    {
        // set a flag to break the loop
    }
}

这会如何打破另一个方法中的 while 循环? - zetar
你可以创建一个标志/全局变量,在 while 循环内部进行验证,如果按下键,则更改其状态并退出 while 循环。 - Butzke
我认为在WPF中,除非你为循环创建另一个线程,否则它不起作用。否则,WPF将尝试在响应任何KeyDown消息之前完成循环。 - Dronz

1

MainWindow.xaml:

<Window x:Class="WpfApplication34.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Width="525"
        Height="350">
  <Grid>
    <TextBlock x:Name="tb" />
  </Grid>
</Window>

MainWindow.xaml.cs:

public partial class MainWindow:Window {
  private int _someVal = 0;
  private readonly CancellationTokenSource cts = new CancellationTokenSource();

  public MainWindow() {
    InitializeComponent();
    Loaded += OnLoaded;
  }

  private async void OnLoaded(object sender, RoutedEventArgs routedEventArgs) {
    KeyDown += OnKeyDown;
    while (!cts.IsCancellationRequested) {
      await Task.Delay(1000); // Some Long Task
      tb.Text = (++_someVal).ToString();
    }
  }

  private void OnKeyDown(object sender, KeyEventArgs keyEventArgs) {
    if (keyEventArgs.Key == Key.A)
      cts.Cancel();
  }
}

这只是一个粗略的演示,只需理解概念即可。这里唯一与WPF有关的是捕获按键的方式。与打破while循环有关的其他所有内容都适用于控制台应用程序、WPF或WinForms。


对不起,为什么在MainWindow中有一个TextBlock?这只是为了演示输出一些东西吗? - zetar
@zetar 是的,就像 Task.Delay(1000) 一样,它只是用来展示代码正在执行某些操作。 - Viv
@zetar 如果你还没有了解过 CancellationTokenSource,请查看 Cancellation in Managed Threads。通常只有 cts.Token 会被传递到长时间运行的函数中,并且可以在需要的地方调用 ThrowIfCancellationRequested() 等方法。在这个例子中,检测 KeyDown 是唯一的关键点,而不是 CancellationTokenSource。你甚至可以在这里将 cts 切换为 bool,也没问题。 - Viv

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接