【问题标题】:WPF Popup tab key bugWPF 弹出选项卡键错误
【发布时间】:2009-10-19 23:37:35
【问题描述】:

我有一个 WPF Popup 控件,其中包含一个 ListBox 和一个 Button。当我单击Button 时,它应该被禁用。问题是,当我禁用按钮时,Tab 键会从弹出窗口中消失。在将 Button 的 IsEnabled 设置为 false 后,我尝试将焦点设置到 ListBox,但这不起作用。那么,如何将选项卡焦点设置为 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);

【问题讨论】:

    标签: wpf popup focus tab-ordering


    【解决方案1】:

    您需要通过在 Popup 上设置 FocusManager.IsFocusScope property 来定义明确的焦点范围:

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

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

    【讨论】:

    • KeyboardNavigation.TabNavigation="Cycle" 什么都不做。
    • 对不起,你是对的,它是关于焦点范围的。测试了它,它有效,修改了我的答案。
    • 仅供参考,当我测试它时,我已经完全按照您提供的方式保留了您的代码(通过显式调用 Focus 列表框)。意识到这一点,我回去删除它,焦点仍然跳出弹出窗口,这很奇怪。至少现在它可以让你不必使用计时器来延迟设置焦点。
    猜你喜欢
    • 2012-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-27
    • 1970-01-01
    • 1970-01-01
    • 2023-01-10
    相关资源
    最近更新 更多