MoveFocus会跳过控件

时间:2012-07-11 15:41:28

标签: c# wpf focus

我想允许用户使用箭头键在控件中导航。

用户仍然可以使用Tab和Shift + Tab控件进行水平导航,但我希望他们能够垂直导航(这可能会跳过在水平导航时会聚焦的控件)。

如果我在MoveFocus上使用UIElement方法,那么似乎会跳过某些控件,例如按钮和可编辑的组合框。

有谁知道这是为什么?这些控件通常使用TAB进行聚焦,但向上/向下/向下的FocusDirections似乎跳过控件。如果我看一下PredictFocus,它似乎报告按钮应该以这种方式聚焦,但不能编辑可编辑的组合框。

以下演示代码: XAML:

<Window x:Class="Focus.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Width="525"
        Height="350">
    <Window.Resources>
        <Style x:Key="FocusStyle">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Rectangle Stroke="CadetBlue" StrokeThickness="2" />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Content="txtBox1" Width="75"/>
                <TextBox Width="200"
                         Name="txtBox1"
                         Margin="5"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         FocusVisualStyle="{StaticResource FocusStyle}" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Content="button1" Width="75" />
                <Button Width="200"
                        Name="button1"
                        Height="25"
                        Margin="5"
                        Content="Hello"
                        HorizontalAlignment="Left"
                        VerticalAlignment="Top"
                        FocusVisualStyle="{StaticResource FocusStyle}" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Content="txtBox2" Width="75"/>
                <TextBox Width="200"
                         Name="text2"
                         Margin="5"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         FocusVisualStyle="{StaticResource FocusStyle}" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Content="comboBox" Width="75"/>
                <ComboBox Width="200"
                         Margin="5"
                         Name="comboBox"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         FocusVisualStyle="{StaticResource FocusStyle}" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Content="txtBox4" Width="75"/>
                <TextBox Width="200"
                         Margin="5"
                         Name="txtBox4"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         FocusVisualStyle="{StaticResource FocusStyle}" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Content="comboBox2" Width="75"/>
                <ComboBox Width="200"
                         Margin="5"
                          IsEditable="True"
                         Name="comboBox2"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         FocusVisualStyle="{StaticResource FocusStyle}" />
            </StackPanel>
            <TextBlock Margin="3" Text="{Binding FocussedControl.Name, StringFormat=Focused Control: {0}}" />
            <TextBlock Margin="3" Text="{Binding PredictedFocusControl.Name, StringFormat=Predicted Focus {0}}"/>
        </StackPanel>
    </Grid>
</Window>

MainWindow.Xaml.cs:

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

namespace Focus
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }

        public IInputElement FocussedControl
        {
            get { return (IInputElement)GetValue(FocussedControlProperty); }
            set { SetValue(FocussedControlProperty, value); }
        }

        public static readonly DependencyProperty FocussedControlProperty =
            DependencyProperty.Register("FocussedControl", typeof(IInputElement), typeof(MainWindow));

        public DependencyObject PredictedFocusControl
        {
            get { return (DependencyObject)GetValue(PredictedFocusControlProperty); }
            set { SetValue(PredictedFocusControlProperty, value); }
        }

        public static readonly DependencyProperty PredictedFocusControlProperty =
            DependencyProperty.Register("PredictedFocusControl", typeof(DependencyObject), typeof(MainWindow));

        protected override void OnPreviewLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
        {
            FocussedControl = e.NewFocus;
        }

        protected override void OnPreviewKeyDown(KeyEventArgs e)
        {
            base.OnPreviewKeyDown(e);
            if (e.Key == Key.Down)
            {
                var success = (FocussedControl as UIElement).MoveFocus(new TraversalRequest(FocusNavigationDirection.Down));
                System.Diagnostics.Debug.Assert(success);
                PredictedFocusControl = (FocussedControl as UIElement).PredictFocus(FocusNavigationDirection.Down);
            }
            else if (e.Key == Key.Up)
            {
                var success = (FocussedControl as UIElement).MoveFocus(new TraversalRequest(FocusNavigationDirection.Up));
                PredictedFocusControl = (FocussedControl as UIElement).PredictFocus(FocusNavigationDirection.Up);
            }
        }
    }
}

2 个答案:

答案 0 :(得分:1)

我通过玩FocusManager.IsFocusScope="True" Focusable="True"来解决问题,现在它可以工作:

 <Grid>
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <Label Content="txtBox1" Width="75"/>
            <TextBox Width="200"
                     Name="txtBox1"
                     Margin="5"
                     HorizontalAlignment="Left"
                     VerticalAlignment="Top"
                     FocusVisualStyle="{StaticResource FocusStyle}" />
        </StackPanel>
        <StackPanel Orientation="Horizontal" Focusable="True"  FocusManager.IsFocusScope="True">
            <Label Content="button1" Width="75" />
            <Button Width="200" Focusable="True" IsTabStop="True" 
                    Name="button1"  FocusManager.IsFocusScope="True"
                    Height="25"
                    Margin="5"
                    Content="Hello"
                    HorizontalAlignment="Left"
                    VerticalAlignment="Top"
                    FocusVisualStyle="{StaticResource FocusStyle}" />
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Label Content="txtBox2" Width="75"/>
            <TextBox Width="200"
                     Name="text2"
                     Margin="5"
                     HorizontalAlignment="Left"
                     VerticalAlignment="Top"
                     FocusVisualStyle="{StaticResource FocusStyle}" />
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Label Content="comboBox" Width="75"/>
            <ComboBox Width="200" Focusable="True"
                     Margin="5"  IsTabStop="True" 
                     Name="comboBox"
                     HorizontalAlignment="Left"
                     VerticalAlignment="Top"
                     FocusVisualStyle="{StaticResource FocusStyle}" />
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Label Content="txtBox4" Width="75"/>
            <TextBox Width="200"
                     Margin="5"
                     Name="txtBox4"
                     HorizontalAlignment="Left"
                     VerticalAlignment="Top"
                     FocusVisualStyle="{StaticResource FocusStyle}" />
        </StackPanel>
        <StackPanel Orientation="Horizontal" FocusManager.IsFocusScope="True"  Focusable="True">
            <Label Content="comboBox2" Width="75"/>
            <ComboBox Width="200" Focusable="True"
                     Margin="5" IsTabStop="True" 
                      IsEditable="True"
                     Name="comboBox2"
                     HorizontalAlignment="Left"
                     VerticalAlignment="Top"
                     FocusVisualStyle="{StaticResource FocusStyle}" />
        </StackPanel>
        <TextBlock Margin="3" Text="{Binding FocussedControl.Name, StringFormat=Focused Control: {0}}" />
        <TextBlock Margin="3" Text="{Binding PredictedFocusControl.Name, StringFormat=Predicted Focus {0}}"/>
    </StackPanel>
</Grid>

不能告诉你原因......

答案 1 :(得分:0)

我通过在ComboBox中设置IsTabStop = true来修复它,即使Tab正在专注于控件:

<Window x:Class="Focus.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Width="525"
        Height="350">
    <Window.Resources>
        <Style x:Key="FocusStyle">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Rectangle Stroke="CadetBlue" StrokeThickness="2" />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Width="75" Content="txtBox1" />
                <TextBox Name="txtBox1"
                         Width="200"
                         Margin="5"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         FocusVisualStyle="{StaticResource FocusStyle}" />
                <TextBox Width="200"
                         Margin="5"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         FocusVisualStyle="{StaticResource FocusStyle}" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Width="75" Content="button1" />
                <Button Name="button1"
                        Width="200"
                        Height="25"
                        Margin="5"
                        HorizontalAlignment="Left"
                        FocusVisualStyle="{StaticResource FocusStyle}"
                        VerticalAlignment="Top"
                        Content="Hello" />
                <TextBox Width="200"
                         Margin="5"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         FocusVisualStyle="{StaticResource FocusStyle}" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Width="75" Content="txtBox2" />
                <TextBox Name="text2"
                         Width="200"
                         Margin="5"
                         HorizontalAlignment="Left"
                         FocusVisualStyle="{StaticResource FocusStyle}"
                         VerticalAlignment="Top" />
                <TextBox Width="200"
                         Margin="5"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         FocusVisualStyle="{StaticResource FocusStyle}" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Width="75" Content="comboBox" />
                <ComboBox Name="comboBox"
                          Width="200"
                          Margin="5"
                          HorizontalAlignment="Left"
                          VerticalAlignment="Top"
                          FocusVisualStyle="{StaticResource FocusStyle}">
                    <ComboBoxItem Content="Item1" />
                    <ComboBoxItem Content="Item2" />
                    <ComboBoxItem Content="Item3" />
                    <ComboBoxItem Content="Item4" />
                </ComboBox>
                <TextBox Width="200"
                         Margin="5"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         FocusVisualStyle="{StaticResource FocusStyle}" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Width="75" Content="txtBox4" />
                <TextBox Name="txtBox4"
                         Width="200"
                         Margin="5"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         FocusVisualStyle="{StaticResource FocusStyle}" />
                <TextBox Width="200"
                         Margin="5"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         FocusVisualStyle="{StaticResource FocusStyle}" />
            </StackPanel>
            <StackPanel Orientation="Horizontal"  >
                <Label Width="75" Content="comboBox2" />
                <ComboBox Name="comboBox2"
                          Width="200"
                          Margin="5"
                          HorizontalAlignment="Left"
                          VerticalAlignment="Top"
                          IsTabStop="True"
                          FocusVisualStyle="{StaticResource FocusStyle}"
                          IsEditable="True" />
                <TextBox Width="200"
                         Margin="5"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Top"
                         FocusVisualStyle="{StaticResource FocusStyle}" />
            </StackPanel>
            <TextBlock Margin="3" Text="{Binding FocussedControl.Name, StringFormat=Focused Control: {0}}" />
            <TextBlock Margin="3" Text="{Binding PredictedFocusControl.Name, StringFormat=Predicted Focus {0}}" />
        </StackPanel>
    </Grid>
</Window>