Установите фокус на элементе управления текстовым полем в UserControl в wpf

Я создал UserControl, который загружается в представление (окно) в WPF. В моем элементе управления я поставил TextBox. Я не могу сосредоточиться на этом текстовом поле при загрузке моего представления. Я пробовал следовать, но ничего не работает для меня:

  • FocusManager.FocusedElement="{Binding ElementName=PwdBox}"

  • Я создал FocusExtension, чтобы установить фокус на управление.

Пожалуйста, помогите.

Ответ 1

Другой вариант, который у вас есть, - создать свойство 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;

Ответ 2

Это похоже на ответ Шеридана, но не требует, чтобы фокус был настроен на управление первым. Он запускается, как только элемент управления становится видимым и основывается на родительской сетке, а не на самом текстовом поле.

В разделе "Ресурсы":

    <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}" />

Ответ 3

Фокус клавиатуры будет установлен, если установлено свойство FocusManager.FocusedElement. Поскольку свойство задается при инициализации элемента, это часто полезно для установки начального фокуса.

Однако это не совсем то же самое, что установка фокуса на загрузку. Если он выгружен и перезагружен, например, фокус клавиатуры не будет двигаться второй раз. Фактическая целевая цель свойства FocusedElement - временные области фокуса (например, когда открывается меню, FocusedElement окна сохраняется отдельно от фокуса клавиатуры, потому что меню представляет собой отдельную область фокусировки - и фокус клавиатуры возвращается к FocusedElement, когда меню закрыто). Если вы установите FocusedElement в окне, оно не будет сохраняться - поскольку окно является областью фокуса, оно автоматически обновляет 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}"

Ответ 4

Зарегистрируйте Загруженное событие вашего UserControl и установите Focus на свой PwdBox, вызвав Focus(), когда загружен ваш UserControl.

public class MyUserControl : UserControl{

  public MyUserControl(){
    this.Loaded += Loaded;
  }

  public void Loaded(object sender, RoutedEventArgs e){
    PwdBox.Focus();
    // or FocusManager.FocusedElement = PwdBox;
  }
}

Ответ 5

Что я использую в моем диспетчере аутентификации:

private void SelectLogicalControl()
{
    if (string.IsNullOrEmpty(TextboxUsername.Text))
        TextboxUsername.Focus();
    else
    {
        TextboxPassword.SelectAll();
        TextboxPassword.Focus();
    }
}

Если имя пользователя не задано, сосредоточьтесь на имени пользователя-текстовом поле; в противном случае (выберите все). Это находится в файле codebehind, поэтому не viewmodel;)

Ответ 6

Мне удалось просто добавить этот атрибут в открывающий тег UserControl в моем XAML:

FocusManager.FocusedElement="{Binding ElementName=DisplayName, Mode=OneTime}"

Если DisplayName - это имя текстового поля, я хочу получать фокус.

Ответ 7

При загрузке события установите фокус клавиатуры:

Keyboard.Focus(control);