1

出于某种原因,我的程序需要在函数中暂停,同时仍对用户输入做出反应。目前这是DoEvents在循环中使用的。

不幸的是,我在循环textbox中时无法正常工作。DoEvents我无法输入。似乎可以让KeyDownKeyUp事件正常,但Text属性和显示不显示我正在输入的内容。

为了让事情变得更神秘,它会对退格和 Ctrl+V 做出反应来粘贴文本,仅仅输入它是行不通的。一旦我停止循环,它就会再次正常工作。

有任何想法吗?

附件是一个演示该问题的示例。以防万一我在 VS2010 上使用 VB。

这是 xaml 文件:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="200" Width="200">
    <StackPanel>
        <TextBox x:Name="txtTest" Text="Testing" Margin="10"/>
        <Button x:Name="btnStartLoop" Content="Start DoEvents Loop"         
                Click="StartLoop_Click" Margin="10"/>
        <Button x:Name="btnStopLoop" Content="Stop DoEvents Loop" 
                Click="StopLoop_Click" Margin="10"/>
    </StackPanel>
</Window>

这是 xaml.vb 文件:

Class MainWindow
    Private stopLoop As Boolean = False

    Private Sub StartLoop_Click(ByVal sender As System.Object, 
                                ByVal e As System.Windows.RoutedEventArgs)
        stopLoop = False
        LoopFunction()
    End Sub

    Private Sub LoopFunction()
        While stopLoop = False
            System.Windows.Forms.Application.DoEvents()
            System.Threading.Thread.Sleep(1)
        End While
    End Sub

    Private Sub StopLoop_Click(ByVal sender As System.Object, 
                               ByVal e As System.Windows.RoutedEventArgs)
        stopLoop = True
    End Sub
End Class
4

2 回答 2

1

我认为你不应该Application.DoEvents用于此目的。WPF 有自己的事件处理机制,Dispatchers因此我认为您应该使用它Dispatcher来处理消息。调度程序有自己的消息队列,我假设 WPF 将一些消息直接发送到调度程序而忽略 Windows 消息队列。

如果您仍想使用类似 DoEvents 的 hack,我建议您改用它:

Dispatcher.BeginInvoke(new Action(() => {}), DispatcherPriority.Background);

另一个单独的问题是,你为什么要在这里使用这种 hacky 方法?无论如何,在 Windows 世界中停止主线程并不是一个好主意。

于 2011-11-30T12:22:37.727 回答
0

看看ElementHost.EnableModelessKeyboardInterop(Window)方法,它会让你的wpf窗口控件在使用Winform's DoEvent函数时正常工作。

于 2019-03-07T09:56:03.990 回答