Текстовое поле WPF не реагирует на ввод в цикле DoEvents - PullRequest
1 голос
/ 30 ноября 2011

По какой-то причине моей программе нужно приостановить функцию, все еще реагируя на ввод пользователя. В настоящее время это делается с помощью DoEvents в цикле.

К сожалению, мой textbox не работает должным образом, пока я нахожусь в цикле DoEvents. Я не могу набрать это. Кажется, что все события KeyDown и KeyUp в порядке, но свойство Text и отображение не показывают то, что я печатаю.

Чтобы сделать вещи более загадочными, он реагирует на клавишу возврата и Ctrl + V, чтобы вставить текст, просто набрав его, не работает. Это работает снова хорошо, как только я остановлю цикл.

Есть идеи?

Прилагается пример, демонстрирующий проблему. На всякий случай важно использовать VB на VS2010.

Это файл 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

Ответы [ 2 ]

1 голос
/ 30 ноября 2011

Я думаю, вы не должны использовать Application.DoEvents для этой цели.WPF имеет свой собственный механизм обработки событий через Dispatchers, поэтому я думаю, что вы должны использовать Dispatcher для обработки сообщений.Диспетчеры имеют свои собственные очереди сообщений, и я предполагаю, что WPF отправляет некоторые сообщения непосредственно Диспетчеру, игнорируя очередь сообщений Windows.

Если вы все еще хотите использовать DoEvents-подобный хак, я бы рекомендовал использовать вместо этого:

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

И еще один отдельный вопрос: почему вы хотите использовать такой хакерский подход здесь?В любом случае остановка основного потока не является хорошей идеей в мире Windows.

0 голосов
/ 07 марта 2019

Взгляните на метод ElementHost.EnableModelessKeyboardInterop(Window), он обеспечит корректную работу вашего wpf окна при использовании Winform's DoEvent fuction.

...