Silverlight KeyDown event in behavior

5.9k views Asked by At

In my Silverlight 4 DataGrid control, I wanted to attach a very simple Behavior which executes a custom command on key Press - actually, commit the selected item in the DataGrid on ENTER key press.

While the Behavior actually works (see my code...

//.... in "OnAttached()..."
this.AssociatedObject.AddHandler(Control.KeyDownEvent, new KeyEventHandler(OnKeyDown), true);

private void OnKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            InvokeCommand();
        }
    }

...) I have the problem, that the DataGrid seems to handle the ENTER key press itself and proceeds to the next row. Obviously, what happens is that the wrong Row is committed, because when I handle the Key Press, the row selectedion has already changed.

Here is the XAML:

<data:DataGrid
      AutoGenerateColumns="False"
      IsReadOnly="True"
      ItemsSource="{Binding Path=Data}"
      SelectedItem="{Binding SelectedRow, Mode=TwoWay}">
   <data:DataGrid.Columns>
      <data:DataGridTextColumn Binding="{Binding A}" />
      <data:DataGridTextColumn Binding="{Binding B}" />
      <data:DataGridTextColumn Binding="{Binding C}" />
   </data:DataGrid.Columns>
   <i:Interaction.Behaviors>
      <behaviors:EnterBehavior Command="{Binding CommitCommand}" />
   </i:Interaction.Behaviors>
</data:DataGrid>

Can you tell me how I can prevent the default ENTER event?

3

There are 3 answers

0
MarcE On BEST ANSWER

Guess it's a bit late now to help the OP, but I solved this by subclassing the data grid and overriding the KeyDown method to set e.Handled to true. That stops the default enter processing of the DataGrid, then your own actions can take effect.

(Obviously you have to replace instances of DataGrid in the XAML with YourCustomDataGrid)

public class YourCustomDataGrid : DataGrid
{
    protected override void OnKeyDown(KeyEventArgs e)
    {
        // Stop "Enter" selecting the next row in the grid
        if (e.Key == Key.Enter)
        {
            e.Handled = true;
        }
        base.OnKeyDown(e);
    }
}
2
Masterfu On

See if using the AddHandler overload with handledEventsToo can help you here. In certain cases, this allows you to get your handler invoked even if a previous handler already set handled=true.

0
Martin On

Don't rely on SelectedRow, use the row that raised the event in the first place as a parameter for your submit operation. See code below:

private void OnKeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.Enter) 
    { 
        InvokeCommand(e.OriginalSource); 
    }
}