Скрытие / отображение дочерних элементов управления, когда родительский элемент управления получает / теряет фокус - PullRequest
1 голос
/ 08 декабря 2010

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

Элемент управления имеет следующую структуру:

<UserControl x:Class="MyRichTextBoxControl">
 <Grid>
  <Grid.RowDefinitions>
   <RowDefinition Height="Auto" />
   <RowDefinition Height="*" />
  </Grid.RowDefinitions>
  <StackPanel x:Name="_formattingToolBar" Grid.Row="0" Orientation="Horizontal">
   <Button Content="Bold" ... />
   <!-- other buttons -->
  </StackPanel>
  <RichTextBox x:Name="_richTextBox" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
 </Grid>
</UserControl>

Начальный удар

Сначала я попробовал очевидное, я переопределил OnGotFocus и OnLostFocus на родительском UserControl и спрятал / показал _formattingToolbar соответственно.Это не работает, потому что, если дочерний элемент управления получает фокус, Silverlight считает, что родительский элемент управления потерял фокус.В результате попытки щелкнуть панель инструментов приводит к ее исчезновению.

Неприятное решение

Пока что единственное решение, которое я нашел, - это подключить обработчики событий к GotFocus и LostFocus события для каждого отдельного дочернего элемента управления и родительского элемента управления UserControl.Обработчик события вызовет FocusManager.GetFocusedElement(), и если найденный элемент окажется дочерним по отношению к моему UserControl, то оставьте видимым _formattingToolbar, иначе сверните его.Я уверен, что это будет работать, но это довольно уродливо.

Также возможно, что эта идея ошибочна, потому что GotFocus / LostFocus запускаются асинхронно, в то время как GetFocusedElement() определяется синхронно.Могли ли быть какие-то условия гонки, из-за которых моя идея провалилась?

Кто-нибудь знает лучшее решение?

Ответы [ 2 ]

0 голосов
/ 21 мая 2014
    protected override void OnLostFocus(RoutedEventArgs e)
    {
        base.OnLostFocus(e);
        object focusedElement = FocusManager.GetFocusedElement();

        if (focusedElement is UIElement)
        {
            if (!this.LayoutRoot.Children.Contains((UIElement)focusedElement))
            {
                // Do your thing.
            }
        }
        else { /**/ }
    }
0 голосов
/ 08 декабря 2010

Нитин Мидха, у тебя была правильная идея.Это вернуло меня к моей первоначальной попытке, и небольшое изменение OnLostFocus делает свое дело:

    protected override void OnLostFocus(RoutedEventArgs e)
    {
        base.OnLostFocus(e);

        if (!IsChild(FocusManager.GetFocusedElement()))
        {
            HideToolbar();
        }
    }
...