Установите фокус на текстовое поле в xaml wpf

91

Несмотря на некоторые сообщения на этом и других форумах, я не могу найти что-то, что подсказывало бы мне, как сосредоточить внимание на файле TextBox.

У меня есть userControl со многими ярлыками и текстовыми полями. Когда форма загружена, я хочу, чтобы конкретный текстовый блок имел фокус.

Я установил tabIndex, но это не сработало.

Какие-либо предложения?

user9969
источник
Возможный дубликат WPF и первоначальный фокус
Рубен Бартелинк 01

Ответы:

177

Для этого можно использовать FocusManager.FocusedElementприкрепленное свойство. Вот фрагмент кода, который по умолчанию устанавливает фокус на TxtB.

<StackPanel Orientation="Vertical" FocusManager.FocusedElement="{Binding ElementName=TxtB}">
    <TextBox x:Name="TxtA" Text="A" />
    <TextBox x:Name="TxtB" Text="B" />
</StackPanel>

Вы также можете использовать TxtB.Focus()код программной части, если не хотите делать это в XAML.

Жюльен Лебоскен
источник
13
@TarkaDaal: комментарий «у меня не сработало» можно было бы немного проработать. Вероятно, это еще один элемент управления, который крадет фокус. Когда в WPF начинается война фокуса, все идет наперекосяк! Проверьте свои элементы управления и свое текущее местоположение в визуальном дереве (например, в шаблоне ComboBox это не повлияет, и существует множество других подобных случаев). Если вы не можете найти стилера, используйте поведение или программный код, чтобы установить фокус на элемент управления при его загрузке.
Жюльен Лебоскен
@JulienLebosquain: Это был довольно простой элемент управления, две кнопки и текстовое поле в сетке (куда я положил FocusManagerматериал). В конце концов, я сделал это в коде программной части.
TarkaDaal
Элемент FocusedElement не распознан или недоступен. :( plus.google.com/photos/+HendyIrawan/albums/5990385944888867505/…
Hendy Irawan
@HendyIrawan Может быть, это проект Silverlight?
MojoFilter
@MojoFilter, это проект WPF для Windows Phone 8
Хенди Ираван,
26

Вы можете применить это свойство непосредственно к TextBox:

<TextBox Text="{Binding MyText}" FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"/>
Максимум
источник
17
У меня не сработало, установка FocusManager.FocusedElement = "{Binding ElementName = TxtB}" в контейнере действительно сработала
Grant
1
Работает как шарм и не требует именования.
Саймон Мэттс
1
У меня тоже не сработало. Мы что-то упускаем?
BrunoLM 05
1
У меня тоже не сработало. Предложение работы Жюльена Лебоскена.
Crypt32
1
У меня тоже не работает. Все остальные предложенные методы также не работают. Эта проблема должна быть элементарной и легко решаемой .. Вот почему многие люди не любят wpf.
IgorStack
6

Я новичок в использовании WPF и читая приведенные выше примеры. У меня был аналогичный опыт, когда я пытался установить фокус на текстовое поле, используя приведенные примеры кода xaml, т.е. все приведенные выше примеры не работали.

Я обнаружил, что мне нужно поместить FocusManager.FocusElement в элемент страницы. Я предполагаю, что это, вероятно, также сработало бы, если бы вы использовали Window в качестве родительского элемента. В любом случае, вот код, который у меня сработал.

 <Page x:Class="NameOfYourClass"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  mc:Ignorable="d"
  Title="Title" 
  Height="720"
  Width="915"
  Background="white"
  Loaded="pgLoaded"
  FocusManager.FocusedElement="{Binding ElementName=NameOfYourTextBox}">

  <!-- Create child elements here. -->

  </Page>
Джозеф Мауэр
источник
0

привяжите элемент, на который вы хотите указать фокус, как

FocusManager.FocusedElement= "{Binding ElementName= Comobox1}"

в сетке или групповом ящике и т. д.

Суфиан Башир
источник
4
Угу, да, спасибо за тот же ответ, что и все остальные ... 4 года спустя ...
Адам Плохер
4
@AdamPlocher Отличный, вы навсегда отключили Sulfian от Stack Overflow. Сообщение «Добро пожаловать в переполнение стека» было бы более подходящим.
Contango
2
@Contango: "Последний раз видели Nov 11 '14". Он ушел задолго до того, как Адам оставил свой комментарий :)
Gone Coding
0

FocusManager не входил в состав intellisense, и это меня немного смутило. Я просто набрал весь атрибут, и он сработал.

FocusManager.FocusedElement = "{Binding ElementName = MyTextBox}"


Microsoft Visual Studio Enterprise 2015 версии 14.0.23107.0/C#/WPF

icernos
источник
0

Для полноты, есть также способ справиться с этим из кода (например, в случае элементов управления, которые по какой-либо причине создаются динамически и не существуют в XAML). Присоедините обработчик к событию Loaded окна, а затем используйте метод ".Focus ()" нужного вам элемента управления. Пример с голыми костями ниже.

public class MyWindow
{
    private VisualCollection controls;
    private TextBox textBox;

    // constructor
    public MyWindow()
    {
        controls = new VisualCollection(this);
        textBox = new TextBox();
        controls.Add(textBox);

        Loaded += window_Loaded;
    }

    private void window_Loaded(object sender, RoutedEventArgs e)
    {
        textBox.Focus();
    }
}
Роберт Н
источник
0

Поэкспериментировав, решение xaml

FocusManager.FocusedElement="{Binding ElementName=yourElement}"

кажется, работает лучше всего, когда вы помещаете его в самый верхний элемент в иерархии окон (обычно Window или Grid, в которые вы помещаете все остальное)

Тан Цзин Юань
источник
0

Применение: local:FocusManager.FocusOnLoad="True"

    public class FocusManager
    {
        public static readonly DependencyProperty FocusOnLoad = DependencyProperty.RegisterAttached(
            "FocusOnLoad",
            typeof(bool),
            typeof(FocusManager),
            new UIPropertyMetadata(false, new PropertyChangedCallback(OnValueChanged))
            );

        private static void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            if (!(sender is Control control))
                return;

            if ((bool) e.NewValue == false)
                return;

            control.Loaded += (s, e) => control.Focus();
        }

        public static bool GetFocusOnLoad(DependencyObject d) => (bool) d.GetValue(FocusOnLoad);

        public static void SetFocusOnLoad(DependencyObject d, bool value) => d.SetValue(FocusOnLoad, value);
    }
СЕРКАН
источник
0

У меня есть TextBox внутри Grid внутри DataTemplate, которому я хочу, чтобы фокус клавиатуры был виден. Я также обнаружил, что

<DataTemplate x:Key="DistanceView" DataType="{x:Type vm:ROI}">
    <Grid FocusManager.FocusedElement="{Binding ElementName=tbDistance}">
        <TextBox x:Name="tbDistance" Grid.Column="1" Grid.Row="1" VerticalAlignment="Bottom"/>
    </Grid>
</DataTemplate>

у меня не сработало.

Однако когда я вызываю Focus () в родительском ContentControl

private void ContentControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if ((sender as ContentControl).IsVisible)
    {
        (sender as ContentControl).Focus();
    }
}

он начинает работать, и в текстовом поле отображается курсор. Я думаю, что FocusScope должен быть в фокусе, чтобы свойство FocusManager.FocusedElement имело какой-либо эффект.

Джерри

Джерри
источник