2012-12-10 2 views
2

F3 키를 누를 때 어떻게 TextBox에 포커스를 맞출 수 있습니까? 즉키 바인딩을 사용하여 xaml에서 텍스트 상자를 어떻게 집중시킬 수 있습니까?

, 어떤 일이 울부 짖는 소리처럼 수행

private void Window_PreviewKeyDown(object sender, KeyEventArgs) 
{ 
     switch (e.Key) 
     { 
      case Key.F3: 
       myTextBox1.Focus(); 
       break; 
      case Key.F4: 
       myTextBox2.Focus(); 
       break; 
      default: 
       break; 
     } 
} 

참고 : 나는 XAML에서 그것을 할 싶어.

+0

실제로 KeyBinding을 사용하여 KeyGesture를 RoutedCommand에 바인딩합니다. 따라서 Keybinding을 사용하려면 원하는대로 포커스를 설정할 수있는 RoutedCommand를 정의해야합니다. 어쨌든 XAML 만 사용할 기회는 없습니다. – Klaus78

답변

5

바로 가기 키를 사용하는 첨부 된 속성을 만든 다음 해당 컨트롤을 호스팅하는 창에 입력 바인딩을 만드는 방법으로 만들 수 있습니다.이 클래스는 복잡한 클래스이지만 매우 사용하기 쉽습니다.

아래에서 프로젝트에 새 클래스를 추가하기 시작하십시오.

public class TextBoxHelper : DependencyObject 
    { 
     public class MvvmCommand : DependencyObject, ICommand 
     { 
      readonly Action<object> _execute; 
      readonly Func<object, bool> _canExecute; 
      public event EventHandler CanExecuteChanged; 
      public MvvmCommand(Action<object> execute, Func<object, bool> canExecute = null) 
      { 
       if (execute == null) throw new ArgumentNullException("command"); 
       _canExecute = canExecute == null ? parmeter => MvvmCommand.AlwaysCanExecute() : canExecute; 
       _execute = execute; 
      } 
      public object Tag 
      { 
       get { return (object)GetValue(TagProperty); } 
       set { SetValue(TagProperty, value); } 
      } 
      public static readonly DependencyProperty TagProperty = DependencyProperty.Register("Tag", typeof(object), typeof(MvvmCommand), new PropertyMetadata(null)); 
      static bool AlwaysCanExecute() 
      { 
       return true; 
      } 
      public void EvaluateCanExecute() 
      { 
       EventHandler temp = CanExecuteChanged; 
       if (temp != null) 
        temp(this, EventArgs.Empty); 
      } 
      public virtual void Execute(object parameter) 
      { 
       _execute(parameter == null ? this : parameter); 
      } 
      public virtual bool CanExecute(object parameter) 
      { 
       return _canExecute == null ? true : _canExecute(parameter); 
      } 
     } 

     public static Key GetFocusKey(DependencyObject obj) 
     { 
      return (Key)obj.GetValue(FocusKeyProperty); 
     } 

     public static void SetFocusKey(DependencyObject obj, Key value) 
     { 
      obj.SetValue(FocusKeyProperty, value); 
     } 

     public static readonly DependencyProperty FocusKeyProperty = 
      DependencyProperty.RegisterAttached("FocusKey", typeof(Key), typeof(TextBoxHelper), new PropertyMetadata(Key.None, new PropertyChangedCallback((s, e) => 
       { 
        UIElement targetElement = s as UIElement; 
        if (targetElement != null) 
        { 
         MvvmCommand command = new MvvmCommand(parameter => TextBoxHelper.FocusCommand(parameter)) 
          { 
           Tag = targetElement, 
          }; 
         InputGesture inputg = new KeyGesture((Key)e.NewValue); 
         (Window.GetWindow(targetElement)).InputBindings.Add(new InputBinding(command, inputg)); 
        } 
       }))); 

     public static void FocusCommand(object parameter) 
     { 
      MvvmCommand targetCommand = parameter as MvvmCommand; 
      if (targetCommand != null) 
      { 
       UIElement targetElement = targetCommand.Tag as UIElement; 
       if (targetElement != null) 
       { 
        targetElement.Focus(); 
       } 
      } 
     } 
    } 

지금 XAML에 당신이 당신의 초점 키를 설정 할 필요가 FocusKey 속성을 지정하고, 예를 들어 아래의 두 텍스트 상자를 가지고, 하나는 F1을 누를 때, F7을 누르면 다른 때 포커스를 취득.

<Window x:Class="WpfApplication5.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WpfApplication5" 
     DataContext="{Binding RelativeSource={RelativeSource Self}}" 
     Title="MainWindow" Height="131" Width="460"> 

    <Grid Margin="10"> 
     <TextBox Margin="0,0,0,60" local:TextBoxHelper.FocusKey="F1" /> 
     <TextBox Margin="0,35,0,0" local:TextBoxHelper.FocusKey="F7" /> 
    </Grid> 
</Window> 
+0

감사합니다. –

+0

문제에 대한 접근 방식을 좋아하지만 TextBox가 UserControl에있는 경우 클래스를 변경하는 방법을 자세히 설명 할 수 있습니까? 이 경우 Window.GetWindow (targetElement) 문은 null을 반환합니다. LogicalTree와 VisualTree를 재귀 적으로 찾아 보려고했지만 이미 포함 된 Window에 도달하지 못했습니다. 귀하의 조언은 크게 감사하겠습니다. – Geoffrey

+0

응용 프로그램에서 단 하나의 창을 가지고 있다면 Application.Current.MainWindow를 사용할 수 있다고 생각합니다. – Andy

관련 문제