2013-02-05 68 views
0

我試圖讓(鍵盤)焦點正常工作具有以下結構的應用聚焦:使用FocusManager,ContentControl中和的DataTemplate

ItemsControl 
    DataTemplate for Item 
    ContentControl 
     DataTemplate for Content (multiple, depending on type) 
     Some container 
      Different controls (mainly textbox or OK button should have focus) 

在每個內容模板的根(「有些容器」) ,我將FocusManager.FocusedElement設置爲模板中的一個控件。在ItemsControl中的所有項目中,只有一個ContentControl實際上是可見的(「當前」)。所以,基本上,我做的第一件事是可見的,其中的確定按鈕有焦點,用戶可以按Enter鍵確認。然後隱藏這一個,顯示下一個,並且其主控制(例如文本框)具有焦點,用戶可以按回車確認(小事件處理以在文本框中輸入確認項目)等等。

當一切都完成後,用戶可以單擊工具欄中的按鈕重新開始,使第一個ContentControl再次可見。但是這次它沒有重點。我不知道誰的重點,我希望它像一開始就工作。我試圖將焦點設置到剛剛顯示的ContentControl(它的作品,通過虛線可見),但它不會將焦點設置給它的子項。由於我不知道選擇了哪個數據模板(當然,不是沒有編寫特殊代碼),我不能隻手動設置焦點或通過綁定到孩子。也許我現在錯過了一件簡單的事情?另一方面,當用戶手動點擊活動的ContentControl按鈕或文本框時,他可以用enter確認,但ItemsControl似乎有焦點,而不是下一個項目。我無法理解這個焦點問題。有一個簡單的解決方案嗎?我是否必須編寫代碼才能從ContentControl遍歷樹來獲取正確的數據模板?然後,我可以只是將數據模板或設置爲FocusedElement的控件集中在一起,還是必須分別爲每個數據模板編寫代碼?

回答

0

您應該實施一個動作,可以從ViewModel觸發,以便在需要時聚焦元素。試試這個代碼:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Interactivity; 
using System.Windows; 

namespace Behaviors 
{ 
    /// <summary> 
    /// Action to focus target element, if invoked when target is not yet specified, will focus once the target is set 
    /// </summary> 
    public class FocusAction : TargetedTriggerAction<DependencyObject> 
    { 
     protected override void OnAttached() 
     { 
      base.OnAttached(); 
     } 
     protected override void OnDetaching() 
     { 
      base.OnDetaching(); 
     } 
     protected override void Invoke(object parameter) 
     { 
      if (Target is UIElement) 
      { 
       if(!((UIElement)Target).IsKeyboardFocusWithin) 
        ((UIElement)Target).Focus(); 
      } 
      else 
       invokeOnConnect = true; 
     } 
     private bool invokeOnConnect = false; 
     protected override void OnTargetChanged(DependencyObject oldTarget, DependencyObject newTarget) 
     { 
      base.OnTargetChanged(oldTarget, newTarget); 
      if (invokeOnConnect) 
      { 
       invokeOnConnect = false; 
       Invoke(null); 
      } 
     } 
    } 
} 

然後在WPF:

<DockPanel> 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="Loaded"> 
      <nuib:FocusAction TargetName="title"/> 
      </i:EventTrigger> 
     <TextBlock x:Name="title"/> 
</DockPanel> 

命名空間:

xmlns:nuib="clr-namespace:Behaviors;assembly=Nui" // for Action class 
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" // .net library for interactivity 
+0

會試試看,但是我不知道是否能解決這個問題。我可以觸發更改的時間點與現在相同(當ContentControls中的一個變爲可見時,我嘗試集中正確的控件,但它失敗並將焦點設置爲以前的ContentControl控件)... – OregonGhost

相關問題