开发者

KeyDown event does not fire for 'enter' in AutoCompleteBox

I am using a Silverlight usercontrol in my ASP.NET web app. The user control has several autocomplete boxes and it seems that the enter key never fires the keydown event in any of them while it fires for other keys.

I'm assuming that autocomplete boxes must handle the enter key in a different way, perhaps for chosing an item from the list. - Thus it works with simple text boxes.

开发者_如何学编程

I was thinking about overriding the eventhandler in a new deriving control...

Have you guys found a solution for this?


Joe White is correct that some controls handle key events on their own, which has the effect of masking them to higher-level controls. If you take a look at the AutoCompleteBox in Reflector you will see that Enter, Escape, and F4 all cause something to happen and mark e.Handled = true.

Unfortunately PreviewKeyDown does not exist in the Silverlight world.

One way I have been able to prevent controls from responding to and capturing these key events is by subclassing the control and overriding the OnKeyDown method. Something like this would allow you to control whether or not the control reacts to the key events:

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

You could then use the the HandleKeyEvents property in XAML to disable the control from handling them:

<local:MyAutoCompleteBox HandleKeyEvents="False"/>

This type of thing would prevent the base AutoCompleteBox from ever marking e.Handled = true and allow the event to bubble so your higher-level control could do something else with it. You could get more specific with which keys were handled if you wanted to prevent other KeyDown events (besides Enter) from breaking.


Schoolboy error - I was so focused on KeyDown that I forgot I could use KeyUp instead... :) It still doesn't answer my orignal question, but at least I could move on!


I don't know about the autocomplete box, but I know that some WPF controls (and probably some Silverlight controls as well) handle some keys on their own, and mark them as Handled. So normally you won't see those events.

The simplest solution is to hook PreviewKeyDown instead. This is pretty much what it's there for.


I based this solution off of Dan Auclair's, simplifying it to remove the dependency property and changing the logic to reflect the use case I think you're looking for.

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜