Wpf ControlTemplate中控件的焦点处理
当您编写自己的控件(其控件模板中包含控件)时,管理焦点的正确方法是什么Wpf ControlTemplate中控件的焦点处理,wpf,focus,controltemplate,Wpf,Focus,Controltemplate,当您编写自己的控件(其控件模板中包含控件)时,管理焦点的正确方法是什么 假设我们有一个CustomControl,它的ControlTemplate中有两个文本框。作为用户和开发人员,我期望以下行为: 调用customControl.Focus()时,模板中的第一个文本框应接收焦点 使用Tab/Shift+Tab向前和向后移动焦点预期会起作用,这意味着: 2.1如果用户在customControl之前的控件中按下具有焦点的Tab键,则焦点应移动到customControl的第一个文本框 2.2
假设我们有一个CustomControl,它的ControlTemplate中有两个文本框。作为用户和开发人员,我期望以下行为:
我已经试过了: a。将CustomControl设置为Focusable=false将启用条件2。但禁用条件1 b。在StackOverflow上,如何将焦点移动到控件模板内的控件的问题出现了很多次。始终提出以下解决方案:
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="PART_TextBox1" Property="FocusManager.FocusedElement" Value="{Binding ElementName=PART_TextBox1}" />
</Trigger>
此解决方案启用条件1和2.1,但破坏条件2.2
感谢您的帮助:)您可以使用第二个选项(“代码>IsFocused属性上的触发器”),只需将CustomControl的
IsTabStop
属性设置为False
即可满足条件2.2。不过,此解决方案的一个大缺陷是,通过将IsTabStop
属性设置回True
,可以很容易地将其撤消
实现目标的另一种方法是放下触发器,处理控件代码中的焦点更改,如下所示:
protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
base.OnGotKeyboardFocus(e);
if (e.NewFocus == this)
{
if (object.ReferenceEquals(e.OldFocus, Template.FindName("PART_TextBox1", this)))
MoveFocus(new TraversalRequest(FocusNavigationDirection.Previous));
else
MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
}
}
我还建议在模板中的任何可聚焦控件上设置属性
IsTabStop={TemplateBinding IsTabStop}
和TabIndex={TemplateBinding TabIndex}
,以便在控件上设置这些属性时,它仍然保持内部导航顺序,并防止/允许使用TAB键导航到每个内部控件。您可以使用第二个选项(触发IsFocused
属性),只需将CustomControl的IsTabStop
属性设置为False
,即可满足条件2.2。不过,此解决方案的一个大缺陷是,通过将IsTabStop
属性设置回True
,可以很容易地将其撤消
实现目标的另一种方法是放下触发器,处理控件代码中的焦点更改,如下所示:
protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
base.OnGotKeyboardFocus(e);
if (e.NewFocus == this)
{
if (object.ReferenceEquals(e.OldFocus, Template.FindName("PART_TextBox1", this)))
MoveFocus(new TraversalRequest(FocusNavigationDirection.Previous));
else
MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
}
}
我还建议在模板中的任何可聚焦控件上设置属性
IsTabStop={TemplateBinding IsTabStop}
和TabIndex={TemplateBinding TabIndex}
,以便在控件上设置这些属性时,它仍然保持内部导航顺序,并防止/允许使用TAB键导航到每个内部控件。值得一读:逻辑焦点处理感谢您的链接。我认为我理解逻辑焦点,引入焦点范围并不能解决问题,在我看来也不是正确的方法。或者你的链接背后还有其他意图吗?没有特别的意图,但是当涉及到焦点相关的事情时,逻辑范围经常被忽略。更新链接:值得一读:逻辑焦点处理感谢你的链接。我认为我理解逻辑焦点,引入焦点范围并不能解决问题,在我看来也不是正确的方法。或者你的链接背后还有其他意图吗?没有特别的意图,但是当涉及到焦点相关的事情时,逻辑范围通常会被忽略。更新链接: