0

SOについて同様の質問をいくつか見ましたが、実際に問題に対処しているようには見えません。これが関数の簡略化されたバージョンです。

Private Sub Check_Quantity(sender As System.Object, e As System.Windows.RoutedEventArgs) _
    Handles textbox_quantity.LostFocus

        Dim worked As Boolean = Integer.TryParse(textbox_quantity.Text, quantity)

        If Not worked Then
            MsgBox("Enter a valid number for the quantity")
            textbox_quantity.Focus()
            textbox_quantity.SelectAll()
            quantity = 0
        End If
End Sub

これはWPFであることに注意することが重要です。私がやりたいことはとても簡単です。誰かがテキストボックスを使い終えると、プログラムは入力したものが数字であることを確認します。もしそうなら、これを整数で固定します。そうでない場合は、修正するように指示し、テキストボックスにフォーカスを保ちます。問題はいくつかありますが、結局のところ、この関数は無限ループで実行されます。この同じ関数はWinFormsでは正常に機能しますが、WPFでは機能しません。

他のいくつかの質問では、メッセージボックスが表示されるとフォーカスが失われると言われていますが、テストではこれは正しくありません。メッセージボックスが呼び出されたかどうかに関係なく、ループします。問題は、textbox_quantity.Focus()の呼び出しです。それがなくても問題なく動作します。textbox_quantity.Focus()はtrueの値を返しますが、そこにあるかどうかに関係なく、フォーカスはテキストボックスに設定されません。何が起こっているのか、そしておそらくそれをどのように修正できるのかについての考えはありますか?

4

2 に答える 2

2

問題は、focus()が呼び出されたときに正確に実行されることです...したがって、フォーカスが他のコントロールに与えられる直前に...したがってループ...私が見つけた回避策は、そのような実行を延期することですSystem.Threading.ThreadPool.QueueUserWorkItemを使用したコード。ただし、focus()はウィンドウスレッドから呼び出す必要があるため、Me.Dispatcher.Invokeも使用する必要があります。
したがって、結果は少し複雑ですが、機能します。

            System.Threading.ThreadPool.QueueUserWorkItem(
                                  Sub()
                       Me.Dispatcher.Invoke(Sub()
                                                sender.Focus()
                                                sender.SelectAll()
                                            End Sub)
                                  End Sub)
于 2012-07-10T09:13:13.987 に答える
0

SelectAll呼び出しの後にFocusを移動するか、e.Handled=trueステートメントをそこに追加してみます。

于 2012-07-06T21:23:05.927 に答える