1

I have a window with several single-line Textboxes and one DataGrid (.Net 4.5 on Windows8).

I'd like to route navigation events (Up/Down/PgUp/PgDn, etc) to the grid, regardless of which control has the focus.

I tried overriding PreviewKeyDown in the main window like this:

private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
    switch (e.Key)
    {
        case Key.Up:
        case Key.Down:
            myDataGrid.RaiseEvent(e);
            break;
    }
}

The problem is that I'm getting a StackOverflowException because the events keep reflecting back to Window_PreviewKeyDown.

I tried the following [ugly] workaround:

bool bEventRaised = false;
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if ( bEventRaised )
    {
        bEventRaised = false;
        return;
    }

    switch (e.Key)
    {
        case Key.Up:
        case Key.Down:
            bEventRaised = true;
            myDataGrid.RaiseEvent(e);
            break;
    }
}

I would have preferred to replace if ( bEventRaised ) with if ( sender == myDataGrid ), but alas, the sender is always the main window.

Nonetheless, this got me a bit further. I am now able to see the keyboard event reaching myDataGrid.PreviewKeyDown, but still - the event does not get fired inside myDataGrid.

I'd love to get some help understanding what I'm doing wrong, or if there's a different way to route the events to the child DataGrid.

Thanks.

AVIDeveloper
  • 2,954
  • 1
  • 25
  • 32
  • Try setting `e.Handled` to true. – Ming Slogar Dec 02 '13 at 14:21
  • Thanks, didn't write in my question, but I already tried it unsuccessfully. If I set `e.Handled = true` before or after calling `myDataGrid.RaiseEvent(e)`, the event is not routed to the DataGrid (doesn't even tickle `myDataGrid.PreviewKeyDown`). – AVIDeveloper Dec 02 '13 at 15:18

1 Answers1

0

Sry about the earlier ans, but the same type of logic could apply using an AttachedEvent Like:

enter image description here

Raise the TextChanged event on the TextBox:

<TextBox Name="TxtBox1"  TextChanged="TxtBox1_TextChanged" />

Listen for the TextChanged at the Grid (this is the power of AttachedEvent, Grid has no natural notion of TextChanged):

<Grid TextBoxBase.TextChanged="Grid_TextChanged" >

Create the AttachedEvent:

   public static readonly System.Windows.RoutedEvent MyTextChanged = EventManager.RegisterRoutedEvent(
        "MyTextChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TextBox));

Code behind:

private void TxtBox1_TextChanged(object sender, TextChangedEventArgs e)
{
    RaiseEvent(new RoutedEventArgs(MyTextChanged, sender));
}

// For demo only: simulate selecting the grid row
// You will have to roll your own logic here
// ***NEVER code like this, very bad form***
private void Grid_TextChanged(object sender, TextChangedEventArgs e)
{
    var textBox = e.Source as TextBox;
    if (textBox == null) return;
    var txt = textBox.Text;
    switch (txt)
    {
        case "a":
            _myGrid._dataGrid.SelectedIndex = 0;
            break;
        case "g":
            _myGrid._dataGrid.SelectedIndex = 1;
            break;
        case "o":
            _myGrid._dataGrid.SelectedIndex = 2;
            break;
        case "p":
            _myGrid._dataGrid.SelectedIndex = 3;
            break;
    }
}
narendra
  • 163
  • 1
  • 6
  • Thanks for the effort, but this is not what I'm looking for. Your code is manually changing the DataGrid's selected item. What I'd like to achieve is this: When a navigation key is pressed inside a TextBox (e.g. PgUp), I want to capture the KeyDown event inside the containing Window/Grid, but then I want to route this key event AS-IS to the DataGrid. I'd like to simulate the PgDn key being pressed inside the DataGrid as if it were the focused control in the first place. – AVIDeveloper Dec 07 '13 at 13:19