2012-05-04 171 views
0

我在我的wpf應用程序中遇到鍵盤導航問題。 簡體中文我有一個水平的堆疊面板,菜單項列表佔用了屏幕寬度的四分之一。wpf鍵盤導航行爲

正下方,我有一個內容控件,佔用整個屏幕的寬度。

內容控件將根據突出顯示的菜單項更改加載的用戶控件。所有的用戶控件中的

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

形式設置的問題是,當我按向下鍵從StackPanel中它試圖給出聚焦到正下方的內網格列。第一列包含可調焦項目,但第二列不包含可調焦項目。 這適用於堆棧面板中第一列直接位於第一列上方的第一對菜單項,但最終我得到的菜單項直接位於第二列,此時我無法向下導航。

我添加了上述xaml中顯示的外部網格,但這沒有幫助。爲什麼焦點不會移動到網格(或內部網格)中可用的第一個可聚焦元素,以及如何將焦點強制到第1列?

我想我可以在我的viewmodel中做到這一點,但我有相當數量的頁面都遭受類似的問題,所以希望有一個更簡單的解決方案,而不是完全重寫和控制所有的鍵盤導航。

任何幫助將不勝感激。

更新:如果我在第一個網格上將可聚焦設置爲true,則導航工作並最終在第1列中顯示,但顯然第一次按下按鍵「出現」時不執行任何操作,因爲焦點正在給予網格。我想類似的行爲,但對於導航跳轉電網直入列1.

回答

0

沒有回答這個問題,所以我會後我的解決方案。我仍然不滿意,因爲它似乎有點黑客,但直到有更好的事情發生..... 如上所述,鍵盤導航似乎與周圍的網格工作,但我不希望網格重點關注。 我所做的是創建一個擴展網格的自定義控件。 我重寫獲取鍵盤焦點,然後查看最後有焦點的元素,並檢查它是否在網格之外(I.E我正在導航到網格中)。 如果是這樣的話,我看看重點可能來自哪個方向。我認爲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); 
    }