I have created an UserControl
which is loaded in a View (Window) in WPF. In my user control I have put a TextBox
. I am unable to set focus on this
What i use in my authentication manager:
private void SelectLogicalControl()
{
if (string.IsNullOrEmpty(TextboxUsername.Text))
TextboxUsername.Focus();
else
{
TextboxPassword.SelectAll();
TextboxPassword.Focus();
}
}
If no username is set, focus on the username-textbox; otherwise the (select all) passwordbox. This is in the codebehind-file, so not viewmodel ;)
On load event set the keyboard focus :
Keyboard.Focus(control);
It worked for me to simply add this attribute to the opening UserControl tag in my XAML:
FocusManager.FocusedElement="{Binding ElementName=DisplayName, Mode=OneTime}"
Where DisplayName is the name of the textbox I want to receive focus.
Register the Loaded-Event of your UserControl and set the Focus on your PwdBox by calling Focus() when your UserControl is loaded.
public class MyUserControl : UserControl{
public MyUserControl(){
this.Loaded += Loaded;
}
public void Loaded(object sender, RoutedEventArgs e){
PwdBox.Focus();
// or FocusManager.FocusedElement = PwdBox;
}
}
Keyboard focus will be set when the FocusManager.FocusedElement
property is set. Since the property is set when an element is initialized, this is often useful for setting initial focus.
However this is not quite the same thing as setting focus on load. If it is unloaded and reloaded, for example, the keyboard focus will not move the second time. The actual intended purpose of the FocusedElement property is for temporary focus scopes (for example, when a menu is opened, the FocusedElement of the window is kept separate from the keyboard focus because the menu is a separate focus scope -- and keyboard focus returns to the FocusedElement when the menu is closed). If you set FocusedElement on a Window, it will not persist -- since a Window is a focus scope, it will automatically update its FocusedElement whenever you move keyboard focus within it.
To set focus on the Loaded
event (without using code-behind), this attached property should work for you:
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();
}
}
The usage is the same as FocusManager.FocusedElement
, i.e.:
local:FocusExtensions.LoadedFocusedElement="{Binding ElementName=PwdBox}"
This is similar to Sheridan's answer but does not require focus to be set to the control first. It fires as soon as the control is made visible and is based on the parent grid rather than the textbox itself.
In the 'Resources' section:
<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>
In my grid definition:
<Grid Style="{StaticResource FocusTextBox}" />