出于某种原因,我的程序需要在函数中暂停,同时仍然对用户输入作出反应。目前,这是在循环中使用DoEvents
完成的。
不幸的是,当我在textbox
循环中时,DoEvents
无法正常工作。我不能输入它。它似乎可以使KeyDown
和KeyUp
事件正常,但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
答案 0 :(得分:1)
我认为你不应该为此目的使用Application.DoEvents
。 WPF有自己的机制来通过Dispatchers
进行事件处理,所以我认为你应该使用Dispatcher
来处理消息。调度程序有自己的消息队列,我假设WPF直接向Dispatcher发送一些消息忽略Windows消息队列。
如果您仍想使用类似DoEvents的黑客,我建议您改用:
Dispatcher.BeginInvoke(new Action(() => {}), DispatcherPriority.Background);
这里另外一个问题是你为什么要在这里使用这种hacky方法?无论如何,停止主线程在Windows世界中并不是一个好主意。
答案 1 :(得分:0)
看看ElementHost.EnableModelessKeyboardInterop(Window)
方法,当使用wpf
功能时,它将使您的Winform's DoEvent
窗口控件正常工作。