2

私は MVVM パターンを使用して WPF アプリケーションに取り組んでおり、フォーカスの問題に遭遇しました。

「オーバーレイ」に全画面スライドがあり、各オーバーレイ内に ContentPresenter があり、データ コンテキストで設定したビュー モデル プロパティにコンテンツをバインドして任意のビュー モデル/ビューを表示するために使用します。

<Grid Name="OverlayContainer"
      FocusManager.IsFocusScope="True"
      KeyboardNavigation.TabNavigation="Cycle"
      IsEnabled="False">

  <Grid.RenderTransform>
    <TranslateTransform x:Name="OverlayContainerTransform"
                        X="{Binding ElementName=OverlayContainer, Path=ActualWidth}" 
                        Y="0"/>
  </Grid.RenderTransform>

  <ContentPresenter x:Name="OverlayContent" Content="{Binding Path=OverlayViewModel"/>

</Grid>

次に、必要に応じてOverlayViewModelプロパティをさまざまなビュー モデルに動的に設定し、データ テンプレートを使用して WPF を取得し、関連するビュー モデルの正しいビューを自動的に表示します。

<DataTemplate DataType="{x:Type ViewModels:AuthorisatonViewModel}">
    <Views:AuthorisatonView/>
</DataTemplate>

ビュー モデルを変更してオーバーレイをスライドさせると、フォーカス スコープをオーバーレイ フォーカス スコープに設定します (これは OverlayContainer.Focus で問題なく実行できるようです)。キーボード フォーカスを取得して、関連するビューの最初のフォーカス可能な要素に移動します。

ここで必要なものを見つけたと思ったのですが、このコードを使用してビジュアル ツリーをたどると、ContentPresenter ( OverlayContent ) を VisualTreeHelper.GetChildrenCount() に渡すと、子が返されないため、下に降りることができないようです。動的ビュー内の要素。

また、 OverlayContainerをアクティブ フォーカス スコープとして設定してから、以下を呼び出してみました。

OverlayContainer.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next))

しかし、それもうまくいきませんでした。

表示しようとしているすべてのビューには、少なくとも 1 つのフォーカス可能な可視の有効な要素があります。

何か案は?

4

1 に答える 1

1

Rachel がスポット 1 だったようです。ビューがまだレンダリングされていないことが判明したため、子の視覚要素はまだ利用できませんでした。フォーカサーを次のように呼び出します。

// Focus on first child element only once rendered
this.OverlayContainer.Dispatcher.BeginInvoke(DispatcherPriority.Render,
                                             new Action<FrameworkElement>(Focuser.FocusOnFirstFocusableChild),
                                             this.OverlayContainer);

すべての子ビジュアル要素にアクセスし、それに応じてフォーカスを設定することができました。

于 2012-08-03T15:46:58.720 に答える