Reputation: 3516
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.
Upvotes: 1
Views: 2140
Reputation: 163
Sry about the earlier ans, but the same type of logic could apply using an AttachedEvent Like:
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;
}
}
Upvotes: 0