AutoCompleteBox中,按下“enter”键无法触发KeyDown事件

3
我在我的ASP.NET网页应用中使用了Silverlight用户控件。该用户控件有多个自动完成框,似乎在任何一个自动完成框中按下回车键都不会触发keydown事件,而其他键则可以触发。
我猜测自动完成框必须以不同的方式处理回车键,可能是为了从列表中选择项目。因此,它可以与简单文本框一起使用。
我正在考虑在新派生控件中覆盖事件处理程序...
你们有没有找到解决办法?

自动完成框是由微软提供的吗?我不知道类名,所以无法查看文档。 - Joe White
是的。它是一个Silverlight控件。但是日期选择器也是如此... - G Berdal
4个回答

4

乔·怀特(Joe White)是正确的,一些控件会自己处理键盘事件,这样就会对更高级别的控件掩盖它们。如果你查看Reflector中的AutoCompleteBox,你会发现Enter、Escape和F4都会导致某些事情发生并标记e.Handled = true。

不幸的是,在Silverlight世界中不存在PreviewKeyDown。

我已经找到了一种方法来防止控件响应和捕获这些键盘事件,那就是子类化控件并重写OnKeyDown方法。像这样的东西将允许您控制控件是否对键盘事件做出反应:

public class MyAutoCompleteBox : AutoCompleteBox
{
    public static readonly DependencyProperty HandleKeyEventsProperty = DependencyProperty.Register(
        "HandleKeyEvents",
        typeof(bool),
        typeof(MyAutoCompleteBox),
        new PropertyMetadata(true));

    public bool HandleKeyEvents
    {
        get { return (bool)GetValue(HandleKeyEventsProperty); }
        set { SetValue(HandleKeyEventsProperty, value); }
    }

    protected override void OnKeyDown(KeyEventArgs e)
    {
        if (this.HandleKeyEvents)
        {
            base.OnKeyDown(e);
        }
    }
}

您可以使用XAML中的HandleKeyEvents属性禁用控件处理它们:
<local:MyAutoCompleteBox HandleKeyEvents="False"/>

这种做法可以防止基础的AutoCompleteBox将e.Handled = true标记,从而允许事件冒泡,以便您的更高级别控件可以对其进行其他操作。如果您想要防止其他KeyDown事件(除Enter之外)中断,可以更具体地处理哪些键被处理。


这似乎是目前为止最好的解决方案!谢谢。 - G Berdal

2

学生式的错误——我太专注于KeyDown了,忘记了我可以使用KeyUp… :)至少我可以继续了,虽然这并没有回答我的原问题。


你说得对,这对于 KeyDown 不起作用... 如果你真的想/需要区分并处理 KeyDown,请看我的答案。 - Dan Auclair
谢谢Dan。非常明智的回答!我也在考虑类似的事情... +1 - G Berdal
KeyUp事件似乎也无法捕获回车事件。 - eremzeit

0

我基于Dan Auclair的解决方案进行了简化,去除了依赖属性,并改变了逻辑以反映我认为您正在寻找的用例。

public class MyAutoCompleteBox : AutoCompleteBox
{
    protected override void OnKeyDown(KeyEventArgs e)
    {
        if (e.Key == Key.Enter && !IsDropDownOpen)
        {
            e.Handled = false;
        }
        else
        {
            base.OnKeyDown(e);
        }
    }
}

0
我不知道自动完成框,但我知道一些WPF控件(以及可能一些Silverlight控件)会自行处理某些键,并将它们标记为已处理。因此,通常你看不到这些事件。
最简单的解决方案是挂钩PreviewKeyDown而不是KeyDown。这基本上就是它存在的原因。

1
据我所知,Silverlight 中不存在 PreviewKeyDown。:( - G Berdal
正确的,SL 4 没有 PreviewKeyDown。 - themaestro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接