我有一个窗口,里面有几个单行文本框和一个DataGrid(Windows8上的.Net 4.5)。
我想将导航事件(向上/向下/ 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。
感谢。
答案 0 :(得分:0)
Sry关于早期的ans,但使用AttachedEvent可以应用相同类型的逻辑 像:
在TextBox上提升TextChanged事件:
<TextBox Name="TxtBox1" TextChanged="TxtBox1_TextChanged" />
在Grid上监听TextChanged(这是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;
}
}