Направляйте события клавиатуры 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;
    }
}
Другие вопросы по тегам