Why does UIElement.MoveFocus() not move the focus

2019-07-01 15:07发布

I have the following visual tree:

<DockPanel>
    <TextBox Name="ElementWithFocus" DockPanel.Dock="Left" />
    <ListBox DockPanel.Dock="Left" Width="200" KeyUp="handleListBoxKeyUp">
        <ListBoxItem>1</ListBoxItem>
        <ListBoxItem>4</ListBoxItem>
        <ListBoxItem>3</ListBoxItem>
        <ListBoxItem>2</ListBoxItem>
    </ListBox>
    <TextBox DockPanel.Dock="Left" />
</DockPanel>

handleListBoxKeyUp is the following:

private void handleListBoxKeyUp(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Enter)
    {
        ((UIElement)sender).MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
    }
}

When the ListBox has keyboard focus (really a ListBoxItem I'd guess), pressing Enter moves the focus to the first item in the ListBox instead of to the following TextBox. Why is this happening and how can I get the Enter key to act like Tab here?

2条回答
smile是对你的礼貌
2楼-- · 2019-07-01 15:26

Another method that gets the code to go to the next text box would be to raise the tab event manually. Replacing your code inside the if statement with the following worked for me:

KeyEventArgs args = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, Key.Tab);
args.RoutedEvent = Keyboard.KeyDownEvent;
InputManager.Current.ProcessInput(args);
查看更多
Melony?
3楼-- · 2019-07-01 15:37

Rather than calling MoveFocus on the sender, you should call it on the original source found in the event args.

The sender parameter will always be the ListBox itself, and calling MoveFocus on that with FocusNavigationDirection.Next will go to the next control in the tree, which is the first ListBoxItem.

The original source of the routed event will be the selected ListBoxItem, and the next control after that is the TextBox that you want to receive focus.

((UIElement)e.OriginalSource).MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
查看更多
登录 后发表回答