Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将WPF键盘事件从主窗口发送到子数据网格';s PreviewKeyDown_C#_Wpf_Datagrid_Childcontrol_Event Routing - Fatal编程技术网

C# 将WPF键盘事件从主窗口发送到子数据网格';s PreviewKeyDown

C# 将WPF键盘事件从主窗口发送到子数据网格';s PreviewKeyDown,c#,wpf,datagrid,childcontrol,event-routing,C#,Wpf,Datagrid,Childcontrol,Event Routing,我有一个窗口,有几个单行文本框和一个数据网格(Windows8上的(.Net 4.5)) 我希望将导航事件(Up/Down/PgUp/PgDn等)路由到网格,而不管哪个控件具有焦点 我尝试在主窗口中覆盖PreviewKeyDown,如下所示: private void Window_PreviewKeyDown(object sender, KeyEventArgs e) { switch (e.Key) { case Key.Up: case K

我有一个窗口,有几个单行文本框和一个数据网格(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,因为事件不断反射回
窗口\u 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)
,但遗憾的是,sender始终是主窗口

尽管如此,这让我更进一步。我现在可以看到键盘事件到达myDataGrid.PreviewKeyDown,但是-该事件不会在myDataGrid内部触发

我很想得到一些帮助,了解我做错了什么,或者是否有其他方式将事件路由到子数据网格


谢谢。

Sry关于早期的ans,但是使用AttachedEvent可以应用相同类型的逻辑 比如:

在文本框上引发TextChanged事件:

<TextBox Name="TxtBox1"  TextChanged="TxtBox1_TextChanged" />
代码隐藏:

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;
    }
}

请尝试将
e.Handled
设置为true。谢谢,我没有在问题中写入内容,但我已经尝试过了,但没有成功。如果我在调用
myDataGrid.RaiseEvent(e)
之前或之后设置
e.Handled=true
,则事件不会被路由到DataGrid(甚至不会挠痒痒
myDataGrid.PreviewKeyDown
)。感谢您的努力,但这不是我想要的。您的代码正在手动更改DataGrid的选定项。我想要实现的是:当在文本框(例如PgUp)内按下导航键时,我希望捕获包含窗口/网格内的KeyDown事件,但随后我希望将该键事件按原样路由到DataGrid。我想模拟在DataGrid内部按下的PgDn键,就好像它首先是聚焦控件一样。
   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;
    }
}