2014-02-21 2 views
3

С постом WPF: How to programmatically remove focus from a TextBox, я знаю, как установить TextBox сосредоточится назад к своему родителю, используя следующий код:Установить фокус обратно на родителя?

// Move to a parent that can take focus 
FrameworkElement parent = (FrameworkElement)textBox.Parent; 
while (parent != null && parent is IInputElement 
         && !((IInputElement)parent).Focusable) 
{ 
    parent = (FrameworkElement)parent.Parent; 
} 

DependencyObject scope = FocusManager.GetFocusScope(textBox); 
FocusManager.SetFocusedElement(scope, parent as IInputElement); 

Есть ли способ, чтобы обобщить этот код (например, функция шаблона), чтобы сделать его работать для других элементов, таких как ComboBox, Canvas, Image и т.д.

+0

Только мысль, как о прохождении объекта типа управления вместо объекта текстового поля? – samar

ответ

2

Это должно быть относительно простым:

FrameworkElement ctrl = control; //or whatever you're passing in, since all controls are FrameworkElements. 

// Move to a parent that can take focus 
FrameworkElement parent = (FrameworkElement)ctrl.Parent; 
while (parent != null && parent is IInputElement 
        && !((IInputElement)parent).Focusable) 
{ 
    parent = (FrameworkElement)parent.Parent; 
} 

DependencyObject scope = FocusManager.GetFocusScope(ctrl); //can pass in ctrl here because FrameworkElement inherits from DependencyObject 
FocusManager.SetFocusedElement(scope, parent as IInputElement); 

Это работает, потому что все элементы управления наследуют от FrameworkElement, который наследуется от DependencyObject. Таким образом, вы можете установить ctrl к любому типу управления вы хотите: ComboBox, TextBox, Button, Canvas и т.д.

1

Да, есть такая возможность, в таких случаях осуществлять attached поведения. Логика при работе с фокусом должна вписываться в обработчик DependencyPropertyChangedEvent.

Вот пример для случая:

XAML

<Window x:Class="RemoveFocusHelp.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:this="clr-namespace:RemoveFocusHelp" 
     WindowStartupLocation="CenterScreen" 
     Title="MainWindow" Height="350" Width="525"> 

    <Grid> 
     <TextBox Name="TestTextBox" 
       this:RemoveFocusBehavior.IsRemoveFocus="False" 
       Width="100" 
       Height="25" 
       Text="TestText" />   

     <Button Name="CreateFocus" 
       Width="100" 
       Height="30" 
       Content="Create Focus" 
       HorizontalAlignment="Left" 
       Click="CreateFocus_Click" /> 

     <Button Name="RemoveFocus" 
       Focusable="False" 
       Width="100" 
       Height="30" 
       Content="Remove Focus" 
       HorizontalAlignment="Right" 
       Click="RemoveFocus_Click" /> 
    </Grid> 
</Window> 

Code-behind

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void CreateFocus_Click(object sender, RoutedEventArgs e) 
    { 
     TestTextBox.Focus(); 
    } 

    private void RemoveFocus_Click(object sender, RoutedEventArgs e) 
    { 
     RemoveFocusBehavior.SetIsRemoveFocus(TestTextBox, true); 
    } 
} 

public class RemoveFocusBehavior 
{ 
    #region IsRemoveFocus Dependency Property 

    public static readonly DependencyProperty IsRemoveFocusProperty; 

    public static void SetIsRemoveFocus(DependencyObject DepObject, bool value) 
    { 
     DepObject.SetValue(IsRemoveFocusProperty, value); 
    } 

    public static bool GetIsRemoveFocus(DependencyObject DepObject) 
    { 
     return (bool)DepObject.GetValue(IsRemoveFocusProperty); 
    } 

    static RemoveFocusBehavior() 
    { 
     IsRemoveFocusProperty = DependencyProperty.RegisterAttached("IsRemoveFocus", 
                  typeof(bool), 
                  typeof(RemoveFocusBehavior), 
                  new UIPropertyMetadata(false, IsRemoveFocusTurn)); 
    } 

    #endregion 

    #region IsRemoveFocus Property Metadata 

    private static void IsRemoveFocusTurn(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 
     Control control = sender as Control; 

     if (control == null) 
     { 
      return; 
     } 

     if (e.NewValue is bool && ((bool)e.NewValue) == true) 
     { 
      FrameworkElement parent = (FrameworkElement)control.Parent; 

      while (parent != null && parent is IInputElement 
            && !((IInputElement)parent).Focusable) 
      { 
       parent = (FrameworkElement)parent.Parent; 
      } 

      DependencyObject scope = FocusManager.GetFocusScope(control); 
      FocusManager.SetFocusedElement(scope, parent as IInputElement); 
     } 
    } 

    #endregion 
} 

Проект доступен на этой link.

Смежные вопросы