WPF弹出窗口的Tab键问题

4
我有一个包含ListBox和Button的WPF Popup控件。当我点击Button时,它应该变为禁用状态。问题是,当我禁用Button时,Tab键会从Popup中移出。我尝试在将Button的IsEnabled设置为false后,将焦点设置到ListBox上,但这并没有起作用。那么,如何将Tab焦点设置到Popup控件内的ListBox上?
以下是我的代码。
Window1.xaml:
<Window x:Class="WpfApplication5.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
    <StackPanel>
        <Button Name="openButton" Content="Open"/>
        <Popup Name="popup" Placement="Center">
            <StackPanel>
                <ListBox Name="listBox"/>
                <Button Name="newItemsButton" Content="New Items"/>
            </StackPanel>
        </Popup>
    </StackPanel>
</Window>

Window1.xaml.cs:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace WpfApplication5
{
    partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            openButton.Focus();
            listBox.ItemsSource = new string[] { "Item1", "Item2", "Item3" };
            listBox.SelectedIndex = 1;

            openButton.Click += delegate { popup.IsOpen = true; };
            popup.Opened += delegate { FocusListBox(); };
            newItemsButton.Click += delegate
            {
                newItemsButton.IsEnabled = false;
                FocusListBox();
            };
        }

        void FocusListBox()
        {
            var i = listBox.ItemContainerGenerator.ContainerFromIndex(
                listBox.SelectedIndex) as ListBoxItem;
            if (i != null)
                Keyboard.Focus(i);
        }
    }
}

以下是屏幕截图:

alt text http://img11.imageshack.us/img11/6305/popuptabkey.png

后续编辑:

我找到了一个解决方法,即延迟调用FocusListBox();,如下所示:

Dispatcher.BeginInvoke(new Action(FocusListBox), DispatcherPriority.Input);
1个回答

4

您需要通过设置FocusManager.IsFocusScope属性在弹出窗口中定义一个显式的焦点范围:

<Popup FocusManager.IsFocusScope="true">
  <!-- your content here -->
</Popup>

这将防止焦点返回到包含元素内的控件。

KeyboardNavigation.TabNavigation="Cycle" 不起作用。 - Jeno Csupor
抱歉,你是对的,这与焦点范围有关。我测试了一下,它可以工作,我修改了我的答案。 - Drew Marsh
1
顺便提一下,当我测试它时,我已经完全按照你提供的代码保留了你的代码后台(包括显式调用焦点列表框)。意识到这一点后,我回去把它删除了,但焦点仍然会跳出弹出窗口,这非常奇怪。至少现在,这将使你不必使用计时器来延迟设置焦点。 - Drew Marsh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接