1

UserControl含む がありTextBoxます。ユーザー コントロールが表示されたら、TextBoxフォーカスを移します。を使用してこれを行う必要がある理由を誰かが明確にすることはできDispatcherますか?

public MyUserControl() 
{
    InitializeComponent();
    this.IsVisibleChanged += VisibilityChanged;
}

ケース 1 (作品):

private void VisibilityChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if (this.Visibility == Visibility.Visible)
    {
        this.Dispatcher.BeginInvoke((Action)delegate
        {
            Keyboard.Focus(this.InputTextBox);
        }, DispatcherPriority.Render);
    }
}

ケース 2 (機能しない):

private void VisibilityChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if (this.Visibility == Visibility.Visible)
    {
        Keyboard.Focus(InputTextBox);
    }
}
4

3 に答える 3

3

の代わりにKeyboard.Focus(InputTextBox);イベントハンドラーを呼び出すことができますか?InputTextBox.IsVisibleChangedthis.IsVisibleChanged

これが機能するthis.IsVisibleChanged場合は、レイアウトパネルが子コントロールを更新する前にイベントが発生していると思われます。つまり、InputTextBoxなしでフォーカスを置いてもイベントが表示されない可能性がありますBeginInvoke

于 2012-12-13T12:28:12.840 に答える
2

おそらく、IsVisibleChangedイベントが (UI スレッドではなく) 別のスレッドで発生したためです。

于 2012-12-13T12:07:26.367 に答える
1

操作しているコントロールは UI スレッドに属します (それが作成された場所であるため)。すべてのコントロールは DispatcherObject から派生するため、control.Dispatcher(またはthis.Dispatcherコントロール内から) コントロールが作成されたスレッドに属する Dispatcher への参照が提供されます。

次に、イベント ハンドラーが実行されているバックグラウンド スレッドから、その Dispatcher のアクションをキューに入れます。なぜバックグラウンド スレッドで実行しているのですか? これはコントロールであるため、ホストに翻弄されます。おそらく、バックグラウンド スレッドに何らかのプログラム ロジックがあり、可視性が (おそらくデータ バインディングを介して) 変更され、その結果、イベント ハンドラーも呼び出されます。バックグラウンド スレッド。

Dispatcher に夢中になり、それを使用して意図されていない魔法のような神秘的な偉業を実行しようとするのを防ぐために、Dispatcher.CurrentDispatcherプロパティとその違いをよく理解してください (私はいくつか見てきました)。開発者がこれに気付いていないため、本当にひどいコードです)。

UI 要素に関連付けられた Dispatcher の概要については、次の記事を確認してください: MSDN Advanced WPF: Threading ModelVerifyAccess()コントロールを操作するアクションを試行する前に呼び出すサンプル コードに注意してください。

于 2012-12-13T12:33:52.837 に答える