【问题标题】:Set focus on another control when a key pressed without code-behind在没有代码隐藏的情况下按下键时将焦点设置在另一个控件上
【发布时间】:2011-08-19 16:54:03
【问题描述】:

我正在实现类似于自动建议控件的功能:我有一个包含TextBoxListBox 的用户控件。当用户输入文本时,我将使用 System.Windows.Interactivity 行为处理它并用一些值填充 ListBox...

一切正常...但我想让用户在按下向下箭头键时选择ListBox 中的项目(即在ListBox 上设置Focus)。

我知道可以在代码隐藏 .cs 文件中处理 TextBoxKeyPressDown 事件,但我该如何避免这种情况?

【问题讨论】:

    标签: wpf focus controls


    【解决方案1】:

    如果您已经使用了应该不是什么大问题的交互性,只需实现您自己的 TriggerAction ,它具有属性 KeyTargetName 来确定何时以及关注什么。将其设置为 EventTrigger 中的 PreviewKeyDown

    示例实现和使用:

    <TextBox>
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="PreviewKeyDown">
                <t:KeyDownFocusAction Key="Down"
                                      Target="{Binding ElementName=lbx}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </TextBox>
    <ListBox Name="lbx" ItemsSource="{Binding Data}" />
    
    class KeyDownFocusAction : TriggerAction<UIElement>
    {
        public static readonly DependencyProperty KeyProperty =
            DependencyProperty.Register("Key", typeof(Key), typeof(KeyDownFocusAction));
        public Key Key
        {
            get { return (Key)GetValue(KeyProperty); }
            set { SetValue(KeyProperty, value); }
        }
    
        public static readonly DependencyProperty TargetProperty =
            DependencyProperty.Register("Target", typeof(UIElement), typeof(KeyDownFocusAction), new UIPropertyMetadata(null));
        public UIElement Target
        {
            get { return (UIElement)GetValue(TargetProperty); }
            set { SetValue(TargetProperty, value); }
        }
    
        protected override void Invoke(object parameter)
        {
            if (Keyboard.IsKeyDown(Key))
            {
                Target.Focus();
            }
        }
    }
    

    测试它并且它有效,注意KeyDown 不是因为箭头键被截获并标记为由TextBox处理。

    【讨论】:

    • 谢谢你,H.B.我认为它会起作用 - 我会尝试并报告结果
    【解决方案2】:

    我不认为你可以避免它

    捕获TextBox的KeyDown事件有什么问题,如果它是向上或向下箭头键,只需在后面的代码中触发ListBox.KeyDown事件?

    如果要提供特定于视图的功能(例如焦点),我认为没有理由不在 MVVM 中使用代码隐藏

    【讨论】:

      【解决方案3】:

      此答案基于H.B. 中的答案,并添加了对检查是否按下 Ctrl 键的支持。这意味着它可以处理组合键,例如用于查找的 Ctrl-F。

      XAML

      <TextBox>
      <i:Interaction.Triggers>
          <i:EventTrigger EventName="PreviewKeyDown">
              <t:KeyDownFocusAction Key="Down" Ctrl="True"
                                    Target="{Binding ElementName=lbx}" />
          </i:EventTrigger>
      </i:Interaction.Triggers>
      </TextBox>
      <ListBox Name="lbx" ItemsSource="{Binding Data}" />
      

      命名空间

      xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
      

      help on adding System.Windows.Interactivity

      依赖属性

      public class KeyDownFocusAction : TriggerAction<UIElement>
      {
          public static readonly DependencyProperty KeyProperty =
              DependencyProperty.Register("Key", typeof(Key), typeof(KeyDownFocusAction));
          public Key Key
          {
              get { return (Key)GetValue(KeyProperty); }
              set { SetValue(KeyProperty, value); }
          }
      
          public static readonly DependencyProperty CtrlProperty =
              DependencyProperty.Register("Ctrl", typeof(bool), typeof(KeyDownFocusAction));
          public bool Ctrl
          {
              get { return (bool)GetValue(CtrlProperty); }
              set { SetValue(CtrlProperty, value); }
          }
      
          public static readonly DependencyProperty TargetProperty =
              DependencyProperty.Register("Target", typeof(UIElement), typeof(KeyDownFocusAction), new UIPropertyMetadata(null));
          public UIElement Target
          {
              get { return (UIElement)GetValue(TargetProperty); }
              set { SetValue(TargetProperty, value); }
          }
      
          protected override void Invoke(object parameter)
          {
              if (Keyboard.IsKeyDown(Key))
              {
                  if (Ctrl == true)
                  {
                      if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
                      {
                          Target.Focus();
                      }
                  }
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-22
        相关资源
        最近更新 更多