我已经创建了一个UserControl
加载在 WPF 中的视图(窗口)中。在我的用户控件中,我放了一个TextBox
. 当我的视图加载时,我无法将焦点设置在此文本框上。我试过以下但对我没有任何作用:
FocusManager.FocusedElement="{Binding ElementName=PwdBox}"
我创建了一个
FocusExtension
将重点放在控制上。
请帮忙。
我已经创建了一个UserControl
加载在 WPF 中的视图(窗口)中。在我的用户控件中,我放了一个TextBox
. 当我的视图加载时,我无法将焦点设置在此文本框上。我试过以下但对我没有任何作用:
FocusManager.FocusedElement="{Binding ElementName=PwdBox}"
我创建了一个FocusExtension
将重点放在控制上。
请帮忙。
您拥有的另一个选择是bool IsFocused
在您的视图模型中创建一个属性。然后你可以添加一个DataTrigger
来设置焦点,当这个属性是true
:
在一个Resources
部分:
<Style x:Key="SelectedTextBoxStyle" TargetType="{x:Type TextBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsFocused}" Value="True">
<Setter Property="FocusManager.FocusedElement"
Value="{Binding RelativeSource={RelativeSource Self}}" />
</DataTrigger>
</Style.Triggers>
</Style>
...
<TextBox Style="{StaticResource SelectedTextBoxStyle}" ... />
请注意,有时,您可能需要先将其设置为 false 以使其聚焦(仅当它已经为 时true
):
IsFocused = false;
IsFocused = true;
这类似于 Sheridan 的回答,但不需要先将焦点设置到控件。一旦控件可见并且基于父网格而不是文本框本身,它就会触发。
在“资源”部分:
<Style x:Key="FocusTextBox" TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=textBoxName, Path=IsVisible}" Value="True">
<Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=textBoxName}"/>
</DataTrigger>
</Style.Triggers>
</Style>
在我的网格定义中:
<Grid Style="{StaticResource FocusTextBox}" />
注册 UserControl 的Loaded-Event并在加载 UserControl 时通过调用Focus()将焦点设置在 PwdBox上。
public class MyUserControl : UserControl{
public MyUserControl(){
this.Loaded += Loaded;
}
public void Loaded(object sender, RoutedEventArgs e){
PwdBox.Focus();
// or FocusManager.FocusedElement = PwdBox;
}
}
设置属性时将设置键盘焦点FocusManager.FocusedElement
。由于属性是在元素初始化时设置的,因此这对于设置初始焦点通常很有用。
但是,这与将重点放在负载上并不完全相同。例如,如果卸载并重新加载,则键盘焦点不会第二次移动。FocusedElement 属性的实际预期用途是用于临时焦点范围(例如,当打开菜单时,窗口的 FocusedElement 与键盘焦点保持分离,因为菜单是单独的焦点范围 - 并且键盘焦点返回到菜单关闭时的 FocusedElement)。如果您在 Window 上设置 FocusedElement,它将不会持续存在——因为 Window 是一个焦点范围,只要您在其中移动键盘焦点,它就会自动更新其 FocusedElement。
要设置事件的焦点Loaded
(不使用代码隐藏),这个附加属性应该适合你:
public static class FocusExtensions {
public static readonly DependencyProperty LoadedFocusedElementProperty =
DependencyProperty.RegisterAttached("LoadedFocusedElement", typeof(IInputElement), typeof(FocusExtension),
new PropertyMetadata(OnLoadedFocusedElementChanged));
public static IInputElement GetLoadedFocusedElement(DependencyObject element) {
return (IInputElement)element.GetValue(LoadedFocusedElementProperty);
}
public static void SetLoadedFocusedElement(DependencyObject element, bool value) {
element.SetValue(LoadedFocusedElementProperty, value);
}
private static void OnLoadedFocusedElementChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) {
var element = (FrameworkElement)obj;
var oldFocusedElement = (IInputElement)e.OldValue;
if (oldFocusedElement != null) {
element.Loaded -= LoadedFocusedElement_Loaded;
}
var newFocusedElement = (IInputElement)e.NewValue;
if (newFocusedElement != null) {
element.Loaded += LoadedFocusedElement_Loaded;
}
}
private static void LoadedFocusedElement_Loaded(object sender, RoutedEventArgs e) {
var element = (FrameworkElement)sender;
var focusedElement = GetLoadedFocusedElement(element);
focusedElement.Focus();
}
}
用法与 相同FocusManager.FocusedElement
,即:
local:FocusExtensions.LoadedFocusedElement="{Binding ElementName=PwdBox}"
我在身份验证管理器中使用的内容:
private void SelectLogicalControl()
{
if (string.IsNullOrEmpty(TextboxUsername.Text))
TextboxUsername.Focus();
else
{
TextboxPassword.SelectAll();
TextboxPassword.Focus();
}
}
如果没有设置用户名,则关注用户名文本框;否则(全选)密码框。这是在代码隐藏文件中,所以不是视图模型;)
我只需将此属性添加到我的 XAML 中的打开 UserControl 标记即可:
FocusManager.FocusedElement="{Binding ElementName=DisplayName, Mode=OneTime}"
其中 DisplayName 是我想要获得焦点的文本框的名称。
在加载事件时设置键盘焦点:
Keyboard.Focus(control);