1

我有一个带有几个单行文本框和一个 DataGrid 的窗口(Windows8 上的 .Net 4.5)。

我想将导航事件(Up/Down/PgUp/PgDn 等)路由到网格,无论哪个控件具有焦点。

我尝试在主窗口中覆盖 PreviewKeyDown,如下所示:

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

问题是我得到了 StackOverflowException 因为事件不断反映到Window_PreviewKeyDown.

我尝试了以下 [ugly] 解决方法:

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。

谢谢。

4

1 回答 1

0

对较早的答案感到抱歉,但是可以使用 AttachedEvent 应用相同类型的逻辑,例如:

在此处输入图像描述

在 TextBox 上引发 TextChanged 事件:

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

在 Grid 上监听 TextChanged(这是 AttachedEvent 的强大功能,Grid 没有 TextChanged 的​​自然概念):

<Grid TextBoxBase.TextChanged="Grid_TextChanged" >

创建附加事件:

   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;
    }
}
于 2013-12-05T21:37:11.180 回答