2

I am wondering if anybody knows why the datepicker will pass standard keys to any parent control's key down routed event, but not the return key?

here's the xaml i wrote:

    <WrapPanel Name="_wpParameters" 
               Grid.Row="0" Grid.Column="0" 
               Orientation="Horizontal" 
               Grid.IsSharedSizeScope="True"
               Keyboard.KeyDown="_wpParameters_KeyDown" >
        <!-- this is where the dynamic parameter controls will be added -->
    </WrapPanel>

Here is the code i was using to check for the return key:

private void _wpParameters_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Return)
    {
        RaiseEvent(new RoutedEventArgs(LoadLiveResultsEvent, this));
    }
}

I was using key down on accident (meant to use key up) but I found it interesting that the standard numeric and / characters were firing the logic, but not the return key. Any Idea's why the return key is not included as a key down key?

Nathan Tregillus
  • 6,006
  • 3
  • 52
  • 91

2 Answers2

3

The KeyDown event is a lower-level text input event that might not behave as expected on certain controls. This is because some controls have control compositing or class handling that provides a higher-level version of text input handling and related events.

As viewed on MSDN...my assumption is that the control is consuming the event and perhaps committing the text to the bindable source and other cleanup and then marking the event as handled.

Aaron McIver
  • 24,527
  • 5
  • 59
  • 88
  • very interesting... I am thinking it probably has to do withe calender control part of the date picker is handling to push of the selectedDate value to put the text within the textbox. but wouldn't they want to allow the event to bubble up for potential use? – Nathan Tregillus Dec 30 '10 at 16:53
  • @N8 Not necessarily as it is a specific control providing a given functionality; versus a framework geared towards providing/allowing extensibility. – Aaron McIver Dec 30 '10 at 16:59
  • Ah, like when the event is fired, the entire composite controls state is in a volatile state. (AKA bound values might be half done binding or something like that. but wouldn't they want to handle the event, get their control (in this case the datepicker) into a solid state, then raise the event again? hope that makes sense. (and thanks again, I'd give you more up votes if i could!) – Nathan Tregillus Dec 30 '10 at 17:26
  • @N8 It does make sense but as the MSDN reference states this is a lower-level event so masking that event to expose other events more relative to the control would be a more suited approach to something that is packaged to provide a given piece of functionality. Abstract the lower-level data to provide higher-level data more approachable by the consumer of the control. – Aaron McIver Dec 30 '10 at 17:38
0

In addition had to mention my solution. I had a parent view, that handle the keyDown event from all child viewmodels. I declared a behavior for special controls like DatePicker,MaskedTextBox,etc... that catch previewKeyDown tunneling event and raise KeyDown bubbling event:

public class EnterPressedBehavior : Behavior<UIElement>
{
    public ICommand EnterPressedCommand { get; private set; }

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.PreviewKeyDown += EnterPressed;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.PreviewKeyDown -= EnterPressed;
    }

    private void EnterPressed(object sender, KeyEventArgs keyEventArgs)
    {
        if (Keyboard.PrimaryDevice != null && Keyboard.PrimaryDevice.ActiveSource != null)
        {
            var eventArgs = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, keyEventArgs.Key) { RoutedEvent = UIElement.KeyDownEvent };

            AssociatedObject.RaiseEvent(eventArgs);
        }
    }
}

this behavior assigned to datePicker:

<DatePicker x:Name="BirthDateDatePicker" Grid.Column="1"
                    Grid.Row="6" Margin="3" HorizontalAlignment="Stretch"                                              
                    IsEnabled="{Binding PersonFieldsEditDenied}"
                    Validation.ErrorTemplate="{StaticResource DefaultValidationTemplate}"
                    AutomationProperties.AutomationId="BirthDateDatePicker">
            <i:Interaction.Behaviors>
                <viewModels:EnterPressedBehavior />
            </i:Interaction.Behaviors>
</DatePicker>

which is listened by parent view:

<Window
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       Title=""
       KeyDown="OnKeyDownHandler">

Code behind:

private void OnKeyDownHandler(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            // your code
        }
    }
Fragment
  • 1,555
  • 1
  • 26
  • 33