私はwpfで修正するこのような単純な問題のように見えることに頭を悩ませていますが、アプリを計画どおりに動作させることができない理由をまだ発見していません。
ユーザーがctrl + fを押すと、wpfアプリケーションにポップアップする小さな検索ボックスがあります。私が欲しいのは、キャレットが検索ボックスのテキストボックス内で点滅し、ユーザーがクリックしなくてもユーザー入力を受け取る準備ができていることです。これは、表示、有効化、ヒットテスト可能、タブストップ可能、フォーカス可能なテキストボックスのxamlコードです。
<TextBox x:Name="SearchCriteriaTextBox" Text="{Binding SearchCriteria}" Focusable="True" IsEnabled="True" IsTabStop="True" IsHitTestVisible="True" Style="{DynamicResource SearchTextBoxStyle}" Grid.Column="1" Margin="5,10,0,5" />
コードビハインドでは、検索ボックスの可視性が影響を受けるときにこのメソッドが呼び出されます。検索ボックスはアプリの起動時に読み込まれます。
/// <summary>
/// Handles events triggered from focusing on this view.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="dependencyPropertyChangedEventArgs">The key event args.</param>
private void OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
if (!((bool) dependencyPropertyChangedEventArgs.NewValue))
{
return;
}
SearchCriteriaTextBox.Focus();
Keyboard.Focus(SearchCriteriaTextBox);
SearchCriteriaTextBox.Select(0, 0);
if (SearchCriteriaTextBox.Text.Length > 0)
{
SearchCriteriaTextBox.SelectAll();
}
}
問題は、コードが呼び出され、コンポーネントがIsFocused = trueになりますが、キーボードフォーカスが得られないことです。私は何かが足りないのですか?別のコントロールがキーボードのフォーカスを激しく保持し続けない限り、私はコーディングしなかったと確信していますが、なぜこのかなり単純なコードが正しく機能しないのでしょうか。
回避策として、Dispatcher
を使用して、後でフォーカスを設定してみてください DispatcherPriority (Input
など)
Dispatcher.BeginInvoke(DispatcherPriority.Input,
new Action(delegate() {
SearchCriteriaTextBox.Focus(); // Set Logical Focus
Keyboard.Focus(SearchCriteriaTextBox); // Set Keyboard Focus
}));
問題の説明から、キーボードフォーカスが設定されていないようです。 WPFには複数のフォーカススコープを含めることができるため、複数の要素に論理フォーカス(IsFocused = true
)ただし、キーボードフォーカスを持つことができ、キーボード入力を受け取る要素は1つだけです。
投稿したコードはフォーカスを正しく設定する必要があるため、キーボードフォーカスをTextBox
の外に移動するには後で何かが発生している必要があります。後でディスパッチャの優先度にフォーカスを設定することで、キーボードフォーカスをSearchCriteriaTextBox
に設定することが最後に行われるようになります。
それが誰かを助けるなら、私はこの問題を抱えていました、そして私のアプリケーションは可視性データバインディングで別々のグリッドに配置された複数のユーザーコントロールを備えたメインウィンドウを持っていました。アプリケーションのビルド時にグリッドが存在していたため、LoadedまたはConstructorで呼び出される.Focus()は、可視性の時間ではなく、ビルド時に呼び出されます。
とにかく、グリッドのMouseEnterイベントで.Focus()を呼び出すことで修正しました。私にとってはうまくいきます。