在没有代码隐藏的情况下按下键时将焦点设置在另一个控件上

时间:2011-08-19 16:54:04

标签: wpf focus controls

我正在实现类似自动提示控制的东西:我有一个包含TextBoxListBox的用户控件。当用户输入文字时,我会使用System.Windows.Interactivity行为进行处理,并使用某些值填充ListBox ...

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

我知道可以在代码隐藏的.cs文件中处理KeyPressDown的{​​{1}}事件但是我该如何避免这种情况?

3 个答案:

答案 0 :(得分:5)

如果您已经使用了不应该成为问题的交互,那么只需实施自己的TriggerAction,其属性为Key& TargetName来确定何时以及要关注什么。将其设置为EventTrigger的{​​{1}}。

示例实施&使用方法:

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(); } } } 没有,因为箭头键被拦截并标记为由TextBox处理。

答案 1 :(得分:3)

我认为你不能避免它

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

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

答案 2 :(得分:0)

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

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

的DependencyProperty

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();
                }
            }
        }
    }
}