开发者

Hiding/showing child controls when parent control gains/loses focus

I am creating a text editing control that contains a RichTextArea and a toolbar for formatting. I want the toolbar to only be visible when the control has focus. However I am finding this difficult to pull off in Silverlight, as Silverlight's focus API is very limited.

The control is structured like this:

<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>

Initial Stab

At first I tried the obvious, I overrode OnGotFocus and OnLostFocus on the parent UserControl and hid/showed _formattingToolbar appropriately. This does not work, because if a child control gains focus, then Silverlight considers the parent control lost focus. The net result is trying to click on the toolbar causes it to disappear.

Nasty开发者_JS百科 Solution

So far the only solution I have found is to hook up event handlers to the GotFocus and LostFocus events on every single child control and the parent UserControl. The event handler will call FocusManager.GetFocusedElement() and if the returned element is found to be a child of my UserControl, then keep _formattingToolbar visible, otherwise collapse it. I'm sure this will work, but it's pretty ugly.

It's also possible this idea is faulty because GotFocus/LostFocus are fired asynchronously, while GetFocusedElement() is determined synchronously. Could there be race conditions causing my idea to fail?

Anyone know of a better solution?


Nitin Midha, you had the right idea. That brought my back to my original attempt and a slight altering of OnLostFocus does the trick:

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

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


    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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜