UWP: фокус на AutoSuggestBox

У меня AutoSuggestBox с видимостью Collapsed. На той же странице просмотра у меня есть кнопка. При нажатии на кнопку я хочу показать AutoSuggestBox. И когда запрос был отправлен или AutoSuggestBox потерял фокус, я хочу снова скрыть его.

Вот AutoSuggestBox и кнопка:

<AutoSuggestBox Name="MainAutoSuggestBox"   
                Grid.Row="2"
                GotFocus="MainAutoSuggestBox_GotFocus"
                Visibility="Collapsed"
                QueryIcon="Find"                               
                QuerySubmitted="MainAutoSuggestBox_QuerySubmitted"
                LostFocus="MainAutoSuggestBox_LostFocus"/>

<Button Name="TopBarSearchButton"
        Content="Button"
        Click="TopBarSearchButton_Click"/>

Мой код программной части:

class SomePage : page
{
    ...
    ...

    private void MainAutoSuggestBox_GotFocus(object sender, RoutedEventArgs e)
    {
        //only for testing purposes
    }

    private void MainAutoSuggestBox_LostFocus(object sender, RoutedEventArgs e)
    {
        MainAutoSuggestBox.Visibility = Visibility.Collapsed;

        //put focus on the page
        this.Focus(FocusState.Programmatic);
    }

    private void MainAutoSuggestBox_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
    {
        //Do something
        //Works fine
    }

    private void TopBarSearchButton_Click(object sender, RoutedEventArgs e)
    {
        HandleSearchButtonClick();
    }

    private void HandleSearchButtonClick()
    {
        if (MainAutoSuggestBox.Visibility == Visibility.Collapsed)
        {
            MainAutoSuggestBox.Visibility = Visibility.Visible;
            MainAutoSuggestBox.Focus(FocusState.Programmatic);
        }
        else
        {       
            MainAutoSuggestBox.Visibility = Visibility.Collapsed;
        }    
    }
}

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

Во время отладки я обнаружил, что при первом нажатии кнопки поток управления достигает строки MainAutoSuggestBox.Focus(FocusState.Programmatic); внутри HandleSearchButtonClick(), но никогда не попадает в

private void MainAutoSuggestBox_GotFocus(object sender, RoutedEventArgs e)

метод, но со второго раза он попадает в

private void MainAutoSuggestBox_GotFocus(object sender, RoutedEventArgs e)

метод.


person ravi kumar    schedule 21.06.2017    source источник
comment
Заголовок UWP.   -  person lindexi    schedule 21.06.2017


Ответы (1)


Давайте сначала разберемся, почему фокус не был установлен в первый раз.

Во-первых, подпишитесь на событие Loaded для MainAutoSuggestBox, внутри обработчика вы обнаружите, что RenderSize для MainAutoSuggestBox равно <0,0>. Это имеет смысл, поскольку вы установили Visibility элемента управления на Collapsed в XAML, в результате чего элемент управления игнорирует все события изменения размера.

Таким образом, к тому времени, когда вторая строка приведенного ниже кода попадает в первый раз, хотя для Visibility установлено значение Visible, элемент управления еще не полностью отрисован, поэтому следующий Focus() не будет действовать. После этого элемент управления завершает рендеринг, и поэтому со второго раза Focus() теперь будет работать правильно.

    MainAutoSuggestBox.Visibility = Visibility.Visible;
    MainAutoSuggestBox.Focus(FocusState.Programmatic);

Есть несколько способов исправить это. Сначала нужно подписаться на событие SizeChanged, а затем в обработчике, только, когда старый размер равен <0,0>, а новый размер - это что-то еще, вы знаете, что рендеринг завершен, вызовите там Focus().

Или, что проще, не устанавливайте для него значение Collapsed в XAML, а делайте это в обработчике событий Loaded, поскольку он будет полностью отрисован перед сворачиванием -

MainAutoSuggestBox.Loaded += (s, e) => MainAutoSuggestBox.Visibility = Visibility.Collapsed;
person Justin XL    schedule 21.06.2017