【问题标题】:Route WPF keyboard events to child DataGrid from MainWindow's PreviewKeyDown从 MainWindow 的 PreviewKeyDown 将 WPF 键盘事件路由到子 DataGrid
【发布时间】:2013-12-18 02:51:16
【问题描述】:

我有一个带有几个单行文本框和一个 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

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

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。

谢谢。

【问题讨论】:

  • 尝试将e.Handled设置为true。
  • 谢谢,没有写我的问题,但我已经尝试过了,但没有成功。如果我在调用myDataGrid.RaiseEvent(e) 之前或之后设置e.Handled = true,则事件不会路由到DataGrid(甚至不会触发myDataGrid.PreviewKeyDown)。

标签: c# wpf datagrid childcontrol event-routing


【解决方案1】:

对前面的答案很抱歉,但是可以使用 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;
    }
}

【讨论】:

  • 感谢您的努力,但这不是我想要的。您的代码正在手动更改 DataGrid 的选定项。我想要实现的是:当在 TextBox(例如 PgUp)内按下导航键时,我想在包含的 Window/Grid 内捕获 KeyDown 事件,但随后我想按原样路由此键事件到数据网格。我想模拟在 DataGrid 中按下的 PgDn 键,就好像它首先是焦点控件一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多