当按下无代码隐藏的键时将焦点设置在另一个控件上

发布于 2024-11-30 06:05:27 字数 377 浏览 0 评论 0原文

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

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

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

I'm implementing something like an autosuggestion control: I have a user control that contains a TextBox and a ListBox. When the user enters text I'm handing it with System.Windows.Interactivity behaviors and filling the ListBox with some values...

Everything works fine... but I want to enable the user to select items in the ListBox (i.e. to set Focus on the ListBox) when the down arrow key is pressed.

I know that it is possible to handle the KeyPressDown event of the TextBox in the code-behind .cs file but how can I avoid this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

允世 2024-12-07 06:05:27

如果您已经使用了交互性,那么这应该不是什么大问题,只需实现您自己的具有属性 Key & 的 TriggerAction 即可。 TargetName 来确定何时以及关注什么。在 PreviewKeyDownEventTrigger 中设置它。

示例实施&使用:

<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 处理。

If you already use Interactivity that should not be much of an issue, just implement your own TriggerAction that has the properties Key & TargetName to indentify when and what to focus. Set it in an EventTrigger for PreviewKeyDown.

Sample implementation & use:

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

Tested it and it works, note that KeyDown does not because the arrow keys are intercepted and marked as handled by the TextBox.

我纯我任性 2024-12-07 06:05:27

我认为你无法避免它

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

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

I don't think you can avoid it

What's wrong with capturing the KeyDown event of the TextBox and if it's an Up or Down arrow key, just trigger the ListBox.KeyDown event in the code behind?

I see no reason not to use code-behind in MVVM if it is to provide view-specific functionality such as focus

樱桃奶球 2024-12-07 06:05:27

该答案基于 HB 的答案,并添加了对检查是否按下 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"

请参阅有关添加 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();
                }
            }
        }
    }
}

This answer is based on the one from H.B., and adds support for checking to see if the Ctrl key is pressed. This means it can handle keycombinations such as 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}" />

Namespaces

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

See 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();
                }
            }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文