WPF:如何在不将焦点从目标控件上移开的情况下将密钥发送到另一个控件

时间:2010-03-09 21:23:48

标签: c wpf wpf-controls

我已经关注this question并且效果很好,但它会从我的发送控件中消失焦点。

我要做的是创建一个像自动完整文本框一样的输入框 - 一个文本框和一个包含匹配项列表的弹出控件。我需要能够获取键,例如Up,Down并将它们路由到弹出控件,然后取出其他键并将它们保存在文本框中。

 switch (e.Key)
        {
            case Key.Down:
            {
                if (!popup.IsOpen)
                {
                    openPopup();
                }
                else
                {
                    PresentationSource source = PresentationSource.FromVisual( itemList );
                    if ( source == null ) return;

                    itemList.RaiseEvent(
                        new KeyEventArgs( Keyboard.PrimaryDevice, source, 0, e.Key )
                            {RoutedEvent = Keyboard.KeyDownEvent} );

                }
                break;
            }
        }

上面的itemList是弹出的控件,一旦我调用RaiseEvent就会转移焦点。

1 个答案:

答案 0 :(得分:1)

好吧看起来很容易......

 <StackPanel>
    <Controls:SearchTextBox x:Name="searchBox" SearchMode="Instant" 
                              PreviewKeyDown="onSearchBoxPreviewKeyDown"
                              KeyDown="onKeyDown" 
                              Search="onSearch" Margin="5" />
    <Popup Name="popup" >
        <ListBox x:Name="itemList" 
                 SelectionMode="Extended" 
                 KeyDown="onItemListKeyDown" 
                 PreviewKeyDown="onPreviewItemListKeyDown"
                 />
    </Popup>
</StackPanel>

在onPreviewItemListKeyDown中执行以下操作

private void onPreviewItemListKeyDown( object sender, KeyEventArgs e )
    {
        switch (e.Key)
        {
            case Key.Down:
            case Key.Up:
            case Key.Enter:
            case Key.Escape:
            case Key.Space:
            {
                // swallow
                break;
            }
            default:
            {
                searchBox.Focus();
                return;
            }
        }
    }

对于您不想在弹出控件中处理的任何键,只需将焦点设置回初始控件即可。正如我们在预览键事件中执行此操作时,即使按下以下键也会传递到我的搜索框控件。

这不'感觉'正确..但它对我有用。