这是我的UI的截图。
所有内容都绑定到Question对象列表:
class Question
{
public Answer[] Answers { get; set; }
public string Text { get; set; }
}
class Answer
{
public bool IsSelected { get; set; }
public string Text { get; set; }
}
这是我为朋友写的一个例子,我仍然是一个相对的MVVM新手。 (我知道在答案中使用像IsSelected这样的UI概念是“不对的”,但它可以在不混淆朋友的情况下工作。)
无论如何,左侧显然是一个ListBox,其中集合作为项目源。右侧是带有此剪切的DataTemplate的ContentPresenter:
<DataTemplate x:Key="question" DataType="{x:Type local:Question}">
<Grid>
<Grid.RowDefinitions> ... </Grid.RowDefinitions>
<TextBlock Text="{Binding Text}" />
<ItemsControl Grid.Row="1"
ItemsSource="{Binding Answers}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding Text}"
GroupName="Answer"
IsChecked="{Binding IsSelected}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</DataTemplate>
我已经设置了输入绑定,因此PageUp和PageDown会在问题中移动。当问题改变时,我想要一个右侧的单选按钮(最好是所选的一个,如果有的话)可以聚焦。目标是让用户使用向上/向下箭头键选择答案,并使用PageUp / PageDown在问题之间移动。
我可以在单选按钮和箭头键中工作,但是当我按空格键选择答案时,焦点会移回列表框。老实说,我可以做到没有列表框得到重点。将Focusable设置为false似乎将我的焦点保持在单选按钮内,但即使我将IsTabStop设置为False,Tab键仍然可以在列表框内获得焦点。
在糟糕的旧WinForms中,我有一个SelectedIndexChanged处理程序,用于找到第一个单选按钮并将其聚焦的列表框,以及GotFocus处理程序,试图像热土豆一样抛弃焦点。由于单选按钮是模板的一部分,因此我没有看到明确或优雅的路径。我怎样才能得到我想要的行为? “重新设计你的用户界面”是一个可以接受的答案,如果它完成了工作,但我希望有一个最小的代码隐藏的解决方案;它让我想起了太多的WinForms。
答案 0 :(得分:0)
您似乎需要使用FocusManager
- 请参阅http://cloudstore.blogspot.com/2008/06/setting-initial-focus-in-wpf.html和http://msdn.microsoft.com/en-gb/system.windows.input.focusmanager.aspx
答案 1 :(得分:0)
我知道你说你不想设计UI,但你可以让ListBox看起来像一个单选按钮列表。不确定WPF ListBox是否会执行您想要的操作,但它会以不同方式获取和保持焦点,您可以设置SelectedIndex属性。
答案 2 :(得分:0)
你可以做的事情:
<RadioButton ...
Loaded="RBAnswer_Loaded"/>
private void RBAnswer_Loaded(object sender, RoutedEventArgs e)
{
var rb = (RadioButton)sender;
var answer = (Answer)rb.DataContext;
if (answer.IsSelected) rb.Focus();
}
(为了摆脱你背后的代码,你可以使用Blend Interactivity的InvokeCommandAction
之类的东西将其封装在命令中......)