2012-08-02 76 views
2

我正在使用MVVM模式处理WPF应用程序,并且遇到焦点问题。无法在WPF MVVM应用程序中动态设置焦点

我在'overlays'和每个覆盖内全屏幕幻灯片我有一个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确定),但是我遇到的问题是我可以' t似乎将键盘焦点转移到相关视图上的第一个可调焦元素,无论它是什么。

我想我找到了我需要here,但使用此代码走可视化树似乎当经过ContentPresenter(OverlayContent)到VisualTreeHelper.GetChildrenCount()时,它返回没有孩子,所以它无法弄清动态视图中的元素。

我也尝试设置OverlayContainer作为活动的重点范围,然后调用:

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

但也未能上班。

我试图显示的所有视图都有至少1个可调焦,可见,启用的元素。

任何想法?

+3

也许尝试在“DispatcherPriority.Render”以后的[DispatcherPriority](http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcherpriority.aspx)导航Visual Tree?当您尝试设置焦点时,有可能无法呈现控件,因此这会让他们有时间首先渲染。 – Rachel 2012-08-03 12:50:02

+0

是的,工作的一种享受 - 非常感谢你:D – 2012-08-03 15:47:35

回答

1

Rachel看起来是第一个 - 事实证明,这个视图还没有呈现出来,所以儿童视觉元素还没有出现。调用我的调焦器像这样:

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

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