3

我在我的 ASP.NET Web 应用程序中使用 Silverlight 用户控件。用户控件有几个自动完成框,似乎 enter 键永远不会在其中任何一个中触发 keydown 事件,而它会触发其他键。

我假设自动完成框必须以不同的方式处理回车键,也许是为了从列表中选择一个项目。- 因此它适用于简单的文本框。

我正在考虑在新的派生控件中覆盖事件处理程序......

你们找到解决方案了吗?

4

4 回答 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)被破坏,您可以更具体地处理哪些键。

于 2010-08-18T15:38:53.020 回答
2

男生错误 - 我太专注于 KeyDown 以至于我忘记了我可以使用 KeyUp 来代替...... :) 它仍然没有回答我的原始问题,但至少我可以继续前进!

于 2010-08-18T13:22:35.543 回答
0

我不知道自动完成框,但我知道一些 WPF 控件(可能还有一些 Silverlight 控件)自己处理一些键,并将它们标记为已处理。所以通常你不会看到这些事件。

最简单的解决方案是挂钩 PreviewKeyDown 。这几乎就是它的用途。

于 2010-08-18T12:58:32.323 回答
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);
        }
    }
}
于 2011-11-11T14:01:45.297 回答