我想允许用户使用箭头键在控件中导航。
用户仍然可以使用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);
}
}
}
}
答案 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>