我正在尝试使用以下结构的应用程序让(键盘)焦点正常工作:
ItemsControl
DataTemplate for Item
ContentControl
DataTemplate for Content (multiple, depending on type)
Some container
Different controls (mainly textbox or OK button should have focus)在每个内容模板(“一些容器”)的根上,我将FocusManager.FocusedElement设置为模板中的一个控件。在ItemsControl中的所有项中,只有一个ContentControls是实际可见的(“当前”项)。因此,基本上,我使第一件事可见,其中的OK按钮具有焦点,用户可以按Enter键确认。然后这一个被隐藏,下一个被显示,并且它的主控件(例如文本框)有焦点,用户可以按enter确认(小事件处理使enter在文本框中确认该项)等等。
完成所有操作后,用户可以单击工具栏中的按钮重新开始,使第一个ContentControl再次可见。但这一次它没有焦点。我不知道谁有焦点,我希望它像一开始一样工作。我试图将焦点设置到刚刚显示的ContentControl (它可以工作,通过虚线可见),但它不会将焦点设置到它的子对象上。因为我不知道选择了哪个数据模板(好吧,不是不写特殊代码),所以我不能只是手动设置焦点或通过绑定到子对象。也许我在这一点上遗漏了一件简单的事情?
另一方面,当用户手动单击active ContentControl按钮或文本框时,他可以使用enter确认,但随后ItemsControl似乎具有焦点,而不是下一项。我就是想不通这个焦点问题。有没有简单的解决方案?我是否必须编写代码来遍历ContentControl中的树以获得正确的数据模板?然后,我是否可以只关注设置为FocusedElement的数据模板或控件,或者必须为每个数据模板单独编写代码?
发布于 2013-02-06 16:02:25
你应该实现一个可以在需要的时候从ViewModel触发到焦点元素的动作。尝试以下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Interactivity;
using System.Windows;
namespace Behaviors
{
/// <summary>
/// Action to focus target element, if invoked when target is not yet specified, will focus once the target is set
/// </summary>
public class FocusAction : TargetedTriggerAction<DependencyObject>
{
protected override void OnAttached()
{
base.OnAttached();
}
protected override void OnDetaching()
{
base.OnDetaching();
}
protected override void Invoke(object parameter)
{
if (Target is UIElement)
{
if(!((UIElement)Target).IsKeyboardFocusWithin)
((UIElement)Target).Focus();
}
else
invokeOnConnect = true;
}
private bool invokeOnConnect = false;
protected override void OnTargetChanged(DependencyObject oldTarget, DependencyObject newTarget)
{
base.OnTargetChanged(oldTarget, newTarget);
if (invokeOnConnect)
{
invokeOnConnect = false;
Invoke(null);
}
}
}
}然后在WPF中:
<DockPanel>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<nuib:FocusAction TargetName="title"/>
</i:EventTrigger>
<TextBlock x:Name="title"/>
</DockPanel>命名空间包括:
xmlns:nuib="clr-namespace:Behaviors;assembly=Nui" // for Action class
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" // .net library for interactivityhttps://stackoverflow.com/questions/14711391
复制相似问题