Не может установить фокус на ребенка UserControl

Привязка не знает, что MyTitle изменилось. Распространенным способом информирования об изменениях является реализация INotifyPropertyChanged; также взгляните на MVVM, который является очень распространенным способом реализации его через DataContext.

38
задан Default 11 February 2013 в 15:29
поделиться

8 ответов

I recently fixed this problem for a login splash screen that is being displayed via a storyboard when the main window is first loaded.

I believe there were two keys to the fix. One was to make the containing element a focus scope. The other was to handle the Storyboard Completed event for the storyboard that was triggered by the window being loaded.

This storyboard makes the username and password canvas visible and then fades into being 100% opaque. The key is that the username control was not visible until the storyboard ran and therefore that control could not get keyboard focus until it was visible. What threw me off for awhile was that it had "focus" (i.e. focus was true, but as it turns out this was only logical focus) and I did not know that WPF had the concept of both logical and keyboard focus until reading Kent Boogaart's answer and looking at Microsoft's WPF link text

Once I did that the solution for my particular problem was straightforward:

1) Make the containing element a focus scope

<Canvas FocusManager.IsFocusScope="True" Visibility="Collapsed">
    <TextBox x:Name="m_uxUsername" AcceptsTab="False" AcceptsReturn="False">
    </TextBox>
</Canvas>

2) Attach a Completed Event Handler to the Storyboard

    <Storyboard x:Key="Splash Screen" Completed="UserNamePassword_Storyboard_Completed">
...
</Storyboard>

and

3) Set my username TextBox to have the keyboard focus in the storyboard completed event handler.

void UserNamePassword_Storyboard_Completed(object sender, EventArgs e)
{
 m_uxUsername.Focus();
}

Note that calling item.Focus() results in the call Keyboard.Focus(this), so you don't need to call this explicitly. See this question about the difference between Keyboard.Focus(item) and item.Focus.

26
ответ дан 27 November 2019 в 03:35
поделиться

WPF поддерживает две различных разновидности фокуса:

  1. Клавиатурный фокус
  2. Логический фокус

FocusedElement свойство получает или устанавливает логический фокус в объеме фокуса. Я подозреваю Ваш TextBox действительно имеет логический фокус, но его содержание объема фокуса не является активным объемом фокуса. Следовательно, это не имеет клавиатурного фокуса.

Таким образом, вопрос, у Вас есть несколько объемов фокуса в Вашем визуальном дереве?

3
ответ дан Tim Cooper 27 November 2019 в 03:35
поделиться

Просто недавно у меня было поле списка, которое поместило некоторый TextBlocks в корпус. Я хотел смочь дважды щелкнуть по текстовому блоку и иметь его, превращаются в TextBox, затем фокусируются на нем и выбирают весь текст, таким образом, пользователь мог только начать вводить новое имя (Сродни Adobe Layers)

Так или иначе я делал это с событием, и оно просто не работало. Чудодейственное средство для меня здесь удостоверялось, что я установил событие на обработанный. Я полагаю, что это устанавливало фокус, но как только событие спустилось по пути, это переключало логический фокус.

Мораль истории, удостоверьтесь, что Вы отмечаете событие, как обработано, которое могло бы быть Вашей проблемой.

7
ответ дан Vassi 27 November 2019 в 03:35
поделиться

Я заметил проблему фокуса, конкретно связанную с хостингом WPF UserControls в ElementHosts, которые содержатся в Форме, которая установлена как ребенок MDI через свойство MdiParent.

Я не уверен, является ли это теми же другими проблемы, испытывают, но Вы роете в детали следующим ссылку ниже.

Проблема с установкой фокуса в WPF UserControl разместила в ElementHost в ребенке WindowsForms форму MDI

1
ответ дан jpierson 27 November 2019 в 03:35
поделиться
  1. Установите для пользовательского элемента управления значение Focusable = "True" (XAML)
  2. Обработайте событие GotFocus на своем элементе управления и вызовите yourTextBox.Focus ()
  3. Обработайте событие Loaded в вашем окне и вызовите yourControl.Focus ()

Когда я набираю текст, у меня есть образец приложения, работающего с этим решением. Если это не работает для вас, должно быть что-то конкретное для вашего приложения или среды, вызывающее проблему. В вашем исходном вопросе я думаю, что проблема связана с привязкой. Надеюсь, это поможет.

3
ответ дан 27 November 2019 в 03:35
поделиться

Это глупо, но работает:

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

private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{

 System.Threading.ThreadPool.QueueUserWorkItem(
                   (a) =>
                        {
                            System.Threading.Thread.Sleep(100);
                            someUiElementThatWantsFocus.Dispatcher.Invoke(
                            new Action(() =>
                            {
                                someUiElementThatWantsFocus.Focus();

                            }));
                        }
                   );

}
16
ответ дан 27 November 2019 в 03:35
поделиться

Я нашел хорошую серию сообщений в блоге о фокусе WPF.

Все они удобны для чтения, но конкретно третья часть занимается установкой фокуса на элемент пользовательского интерфейса в UserControl.

3
ответ дан 27 November 2019 в 03:35
поделиться

"При установке начального фокуса при запуске приложения элемент, на который будет установлен фокус, должен быть подключен к PresentationSource, а для элементов Focusable и IsVisible должно быть установлено значение true. Рекомендуемое место для установки начального фокуса - обработчик события Loaded" (MSDN)

Просто добавьте обработчик события "Loaded" в конструктор вашего окна (или элемента управления), и в этом обработчике вызовите метод Focus() для целевого элемента управления.

    public MyWindow() {
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(MyWindow_Loaded);
    }

    void MyWindow_Loaded(object sender, RoutedEventArgs e) {
        textBox.Focus();
    }
6
ответ дан 27 November 2019 в 03:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: