WPF Фокус в содержимом элемента управления вкладкой при создании новой вкладки - PullRequest
1 голос
/ 08 апреля 2010

Я много занимался поиском в SO и Google вокруг этой проблемы, но, похоже, не могу найти ничего другого, чтобы попробовать.

У меня есть MainView (окно), который содержит вкладку управления. Элемент управления вкладки привязывается к ObservableCollection of ChildViews (пользовательские элементы управления). ViewModel MainView имеет метод, который позволяет добавлять в коллекцию ChildViews, которая затем создает новую вкладку. Когда создается новая вкладка, она становится активной вкладкой, и это отлично работает. Этот метод в MainView вызывается из другой ViewModel (OtherViewModel).

Я пытаюсь установить фокус клавиатуры на первый элемент управления на вкладке (AutoCompleteBox из WPFToolkit *) при создании новой вкладки. Мне также нужно установить фокусировку таким же образом, но БЕЗ создания новой вкладки (поэтому установите фокус на активной в данный момент вкладке).

(* Обратите внимание, что с AutoCompleteBox, похоже, есть некоторые проблемы с фокусом - даже если он имеет фокус, вам нужно отправить MoveNext (), чтобы получить курсор в его окне. Я уже работал над этим) .

Так вот в чем проблема. Фокусировка работает, когда я не создаю новую вкладку, но она не работает, когда я создаю новую вкладку. Обе функции используют один и тот же метод для установки фокуса, но логика создания сначала вызывает метод, который создает новую вкладку и устанавливает ее активной. Код, который устанавливает фокус (в Codebehind ChildView):

        IInputElement element1 = Keyboard.Focus(autoCompleteBox);
        //plus code to deal with AutoCompleteBox as noted.

В любом случае Keyboard.FocusedElement запускается как MainView. После создания вызов Keyboard.Focus, похоже, ничего не делает (сфокусированный элемент по-прежнему остается MainView). Вызов этого без создания вкладки правильно устанавливает фокус клавиатуры на autoCompleteBox.

Есть идеи?

Обновление:

Предложение Бендера наполовину сработало.

Так что теперь в обоих случаях сфокусированным элементом является правильно AutoCompleteBox. Затем я делаю MoveNext (), который устанавливает фокус на TextBox. Я предполагал, что это Textbox является внутренним для AutoCompleteBox, так как фокус был правильно установлен на экране, когда это произошло. Теперь я не уверен. Это все еще поведение, которое я вижу, когда этот код получает удар, когда НЕ выполняет создание. После создания MoveNext () устанавливает фокус на элемент обратно в моем MainView.

Проблема все еще должна соответствовать ответу Бендера, где состояние элементов управления не одинаково в зависимости от того, была создана новая вкладка или нет. Есть еще мысли?

Окончательное обновление

Как уже отмечалось, предложение Майохи сработало.

Я хотел обновить это на случай, если кто-нибудь столкнется с такой же проблемой с AutoCompleteBox. Похоже, что настройка фокуса не активирует его в пользовательском интерфейсе - вам нужно сделать MoveNext для него, чтобы переместить фокус вперед один раз во внутреннее текстовое поле элемента управления. Это основано на моем опыте отладки, который не может быть на 100% научным. Если у меня будет время, я попытаюсь создать небольшой проект репро и передать его команде WPFToolkit.

Ответы [ 2 ]

3 голосов
/ 09 апреля 2010

Вы можете попробовать отложить изменение фокуса с помощью

Dispatcher.BeginInvoke(MyChangeFocusAction, DispatcherPriority.ContextIdle);

Он будет поставлен в очередь после завершения макета и обновления свойств. Я не думаю, что это лучшая практика, но она работает для меня.

1 голос
/ 09 апреля 2010

Элемент управления должен быть видимым, чтобы быть сфокусированным, вы можете попытаться отложить фокусировку, подписавшись на событие IsVisibleChanged, должно сработать нечто подобное следующему:

public static void setFocusLate(this Control control)
        {
            DependencyPropertyChangedEventHandler handler = null;

            handler = delegate
                {
                    control.Focus();
                    control.IsVisibleChanged -= handler;
                };

            control.IsVisibleChanged += handler;
        }
...