views:

89

answers:

4

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?

A: 

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.

Joe White
As far as I know PreviewKeyDown doesn't exist in Silverlight. :(
G Berdal
+1  A: 

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!

G Berdal
You are actually correct that it wouldn't work for KeyDown... see my answer if you really wanted/needed to make the distinction and handle KeyDown instead.
Dan Auclair
Thanks Dan. Very bright answer! I was thinking about something similar... +1
G Berdal
+2  A: 

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.

Dan Auclair
This seems like the best solution so far! Thanks.
G Berdal
A: 

Were you not able to do this ?

private void YourControl_KeyDown(object sender, KeyEventArgs e)
{
      if(e.Key == Key.Enter)
      // Do whatever you wanted to do
}

You will need System.Windows.Input for the Key enum which is predefined

Aswin Ramakrishnan