0

wpf アプリケーションのキーボード ナビゲーションに問題があります。画面の幅の約 4 分の 1 を占めるメニュー項目のリストを含む水平スタックパネルがあります。

そのすぐ下に、画面の幅全体を占めるコンテンツ コントロールがあります。

コンテンツ コントロールは、強調表示されたメニュー項目に基づいて、読み込まれたユーザー コントロールを変更します。すべてのユーザー コントロールは、次の形式でセットアップされます。

<Grid>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid Grid.Column="0" />
        <Grid Grid.Column="1" />
    </Grid>
</Grid>

問題は、スタックパネルから下キーを押すと、そのすぐ下の内側のグリッド列にフォーカスしようとすることです。最初の列にはフォーカス可能な項目が含まれていますが、2 番目の列には含まれていません。これは、最初の列の真上にあるスタックパネルの最初の 2 つのメニュー項目では正常に機能しますが、最終的には 2 番目の列の真上にあるメニュー項目に到達し、この時点で下に移動できなくなります。

上記の xaml に示すように外側のグリッドを追加しましたが、これは役に立ちませんでした。グリッド (または内側のグリッド) で使用可能な最初のフォーカス可能な要素にフォーカスが移動しないのはなぜですか? また、フォーカスを列 1 に強制するにはどうすればよいですか?

ビューモデルでこれを行うことができると思いますが、かなりの数のページがすべて同様の問題に苦しんでいるため、すべてのキーボードナビゲーションを完全に書き直して制御するよりも簡単な解決策を望んでいました.

どんな助けでも大歓迎です。

更新: 最初のグリッドで focuasable を true に設定すると、ナビゲーションが機能し、列 1 で終了しますが、グリッドにフォーカスが与えられているため、最初にキーを押して「表示」されて何もしないことは明らかです。同様の動作が必要ですが、ナビゲーションがグリッドを列 1 に直接ジャンプするようにします。

4

1 に答える 1

0

この質問に対する回答はありませんので、私の解決策を投稿します。少しハックのように見えるので、まだ満足していませんが、もっと良いものが来るまで.....上記のように、キーボードナビゲーションはその周りのグリッドで機能するようですが、グリッドを使用したくありません焦点があります。私が行ったことは、グリッドを拡張するカスタム コントロールを作成することです。キーボード フォーカスの取得をオーバーライドし、最後にフォーカスがあった UIElement を見て、それがグリッドの外側にあることを確認します (つまり、グリッドに移動しています)。もしそうなら、私は焦点がどこから来ている可能性が高いかを調べます. たとえば、PredictFocus は上と左のキーを押すことで発生する可能性があるため、このソリューションは少しハックだと思います。方向が見つかったら、その方向にもう一度フォーカスを移動します。

protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
    {
        UIElement previousFocus = (UIElement)e.OldFocus;
        if (previousFocus != null)
        {
            if (!previousFocus.IsDescendantOf(this))
            {
                if (previousFocus.PredictFocus(FocusNavigationDirection.Up).Equals(this))
                {
                    this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Up));
                }
                else if (previousFocus.PredictFocus(FocusNavigationDirection.Down).Equals(this))
                {
                    this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down));
                }
                else if (previousFocus.PredictFocus(FocusNavigationDirection.Left).Equals(this))
                {
                    this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Left));
                }
                else if (previousFocus.PredictFocus(FocusNavigationDirection.Right).Equals(this))
                {
                    this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Right));
                }
            }
        }
        base.OnGotKeyboardFocus(e);
    }        
于 2012-05-15T00:05:51.390 に答える