Направляйте события клавиатуры WPF в дочерний DataGrid из PreviewKeyDown MainWindow
У меня есть окно с несколькими однострочными текстовыми полями и одним DataGrid (.Net 4.5 в Windows8).
Я хотел бы направить события навигации (вверх / вниз /PgUp/PgDn и т. Д.) В сетку, независимо от того, какой элемент управления имеет фокус.
Я попытался переопределить PreviewKeyDown в главном окне следующим образом:
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
switch (e.Key)
{
case Key.Up:
case Key.Down:
myDataGrid.RaiseEvent(e);
break;
}
}
Проблема в том, что я получаю StackruException, потому что события продолжают отражаться обратно Window_PreviewKeyDown
,
Я попробовал следующий [уродливый] обходной путь:
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;
}
}
Я бы предпочел заменить if ( bEventRaised )
с if ( sender == myDataGrid )
Но, увы, отправитель всегда является главным окном.
Тем не менее, это привело меня немного дальше. Теперь я могу видеть достижение события клавиатуры myDataGrid.PreviewKeyDown
, но все же - событие не запускается внутри myDataGrid.
Я хотел бы получить некоторую помощь, чтобы понять, что я делаю неправильно, или если есть другой способ направить события в дочернюю DataGrid.
Благодарю.
1 ответ
Поговорим о более ранних ответах, но тот же тип логики может применяться с помощью AttachedEvent Like:
Вызовите событие TextChanged в TextBox:
<TextBox Name="TxtBox1" TextChanged="TxtBox1_TextChanged" />
Послушайте TextChanged в Grid (это сила AttachedEvent, Grid не имеет естественного представления о TextChanged):
<Grid TextBoxBase.TextChanged="Grid_TextChanged" >
Создайте AttachedEvent:
public static readonly System.Windows.RoutedEvent MyTextChanged = EventManager.RegisterRoutedEvent(
"MyTextChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TextBox));
Код позади:
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;
}
}