2011-01-27 47 views
0

在WPF中,如何設置標籤的目標,以便訪問鍵將焦點置於ContentControl內的控件如何設置標籤的目標以便訪問鍵將焦點放在ContentControl內的控件上?

我正在使用MVVM,所以我不想在代碼後面添加任何代碼以解決此問題。

我已經嘗試將路徑設置爲「Content」,並且在運行時拋出異常,因爲沒有設置爲內容爲ContentControl的內容的數據類型的轉換器。如果我沒有設置路徑,則焦點設置爲ContentControl本身。

<Label Target="{Binding ElementName=_myContentControl, Path=Content}"/> 
+0

在Ubuntu上,所以不能嘗試自己......如果在ContentControl上設置了Focusable = False,然後只是將Target設置爲ContentControl,會發生什麼? – 2011-01-27 18:45:51

+0

謝謝肯特,我也試過了,它在聚焦時是不會改變焦點的。 – 2011-01-27 18:48:21

回答

2

使用GotFocus事件。

<Label Target="myContentControl" >_Content</Label> 
<ContentControl x:Name="myContentControl" GotFocus="myContentControl_GotFocus"> 

private void myContentControl_GotFocus(object sender, RoutedEventArgs e) 
{ 
    var cc = sender as ContentControl; 
    if (cc != null && cc.Content is UIElement) 
     ((UIElement)cc.Content).Focus(); 
}  

使用分離類FocusBehavior另一種解決方案:

class FocusBehaviour : Behavior<ContentControl> 
{ 
    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     this.AssociatedObject.GotFocus += new System.Windows.RoutedEventHandler(AssociatedObject_GotFocus); 
    } 

    void AssociatedObject_GotFocus(object sender, System.Windows.RoutedEventArgs e) 
    { 
     var c = this.AssociatedObject.Content as UIElement; 
     if (c != null) 
      c.Focus(); 
    } 

    protected override void OnDetaching() 
    { 
     base.OnDetaching(); 
     this.AssociatedObject.GotFocus -= new System.Windows.RoutedEventHandler(AssociatedObject_GotFocus); 
    } 
} 

XAML:

<ContentControl x:Name="myContentControl"> 
    <i:Interaction.Behaviors> 
     <local:FocusBehaviour /> 
    </i:Interaction.Behaviors> 
</ContentControl> 

這種方式需要一個名爲System.Windows.Interactivity的dll,並隨Expression Blend SDK一起安裝。

0

我去的方法是類似vorrtex的想法,但並不需要增加System.Windows.Interactivity

參考創建與它改變時,事件處理程序的布爾附加屬性。將此屬性添加到xaml中的內容控件中。添加屬性後,事件處理程序會觸發,您可以在此處訂閱您的內容控件上獲取的焦點事件。

在獲得的焦點事件處理程序中,您將焦點移至下一個將成爲內容的對象!確保您在內容控件上設置了IsTabStop = False,否則您將無法將Shift + Tab移出內容。

public static bool? GetFocusContent(DependencyObject obj) 
    { 
     return (bool?)obj.GetValue(FocusContentProperty); 
    } 

    public static void SetFocusContent(DependencyObject obj, bool? value) 
    { 
     obj.SetValue(FocusContentProperty, value); 
    } 

    public static readonly DependencyProperty FocusContentProperty = 
     DependencyProperty.RegisterAttached("FocusContent", typeof(bool?), typeof(MyClassName), 
     new UIPropertyMetadata(OnFocusContentChanged)); 

    static void OnFocusContentChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
    { 
     if (((bool?)e.NewValue).Value == true) 
     { 
      ContentControl cControl = obj as ContentControl; 

      if (cControl!= null) 
      { 
       cControl.GotFocus += OnGotFocus; 
      } 
     } 
    } 

    static void OnGotFocus(object sender, RoutedEventArgs e) 
    { 
     ContentControl cControl = sender as ContentControl; 

     // You should check the original source against the sender to make sure that 
     // you don't prevent focus from getting to a child of your content. 
     if (cControl != null && e.OriginalSource == sender) 
     { 
      cControl.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); 
     } 
    } 
1

你也可以使用一個轉換器綁定標籤的TargetContentControlContent

[ValueConversion(typeof(ContentControl), typeof(UIElement))] 
public class ToContentConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     var source = value as ContentControl; 
     if (source == null) 
     { 
      throw new ArgumentException("ToContentConverter source must be a ContentControl."); 
     } 

     return source.Content; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

聲明轉換器:

<Converters:ToContentConverter x:Key="ToContentConverter" /> 

並使用它:

<Label Content="_Thing:" Target="{Binding ElementName=TheContentControl, Converter={StaticResource ToContentConverter}}" /> 
<ContentControl Name="TheContentControl" /> 
相關問題