无法在WPF MVVM应用程序中动态设置焦点

时间:2012-08-02 10:20:31

标签: wpf mvvm focus

我正在使用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做好),但我遇到的问题是我可以似乎无法将键盘焦点转移到相关视图上的第一个可聚焦元素,无论它是什么。

我以为我找到了我需要的内容here但是当使用此代码遍历可视化树时,似乎将ContentPresenter( OverlayContent )传递给VisualTreeHelper.GetChildrenCount()它不返回任何子项,因此无法使动态视图中的元素失效。

我也尝试将 OverlayContainer 设置为活动焦点范围,然后调用:

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

但是也没能奏效。

我想要显示的所有视图中至少包含一个可聚焦,可见,启用的元素。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

Rachel似乎是第一位的 - 结果是视图还没有渲染,所以儿童视觉元素还没有出现。像这样调用我的聚焦器:

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

允许我访问所有子视觉元素并相应地设置焦点。