Silverlight 当父控件获得/失去焦点时隐藏/显示子控件
我正在创建一个文本编辑控件,其中包含一个RichTextArea和一个用于格式化的工具栏。我希望工具栏仅在控件具有焦点时可见。然而,我发现在Silverlight中很难做到这一点,因为Silverlight的FocusAPI非常有限 控件的结构如下所示:Silverlight 当父控件获得/失去焦点时隐藏/显示子控件,silverlight,silverlight-4.0,focus,routed-events,Silverlight,Silverlight 4.0,Focus,Routed Events,我正在创建一个文本编辑控件,其中包含一个RichTextArea和一个用于格式化的工具栏。我希望工具栏仅在控件具有焦点时可见。然而,我发现在Silverlight中很难做到这一点,因为Silverlight的FocusAPI非常有限 控件的结构如下所示: <UserControl x:Class="MyRichTextBoxControl"> <Grid> <Grid.RowDefinitions> <RowDefinition Height
<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>
初刺
起初,我尝试了显而易见的方法,在父用户控件和hid/show格式工具栏上覆盖了OnGotFocus和OnLostFocus。这不起作用,因为如果子控件获得焦点,Silverlight会认为父控件失去焦点。最终的结果是,试图单击工具栏会使其消失
讨厌的解决办法
到目前为止,我找到的唯一解决方案是将事件处理程序连接到每个子控件和父用户控件上的GotFocus和LostFocus事件。事件处理程序将调用FocusManager.GetFocusedElement,如果发现返回的元素是my UserControl的子元素,则保持_formattingToolbar可见,否则将其折叠。我相信这会管用的,但它很难看
这种想法也可能是错误的,因为GotFocus/LostFocus是异步触发的,而GetFocusedElement是同步确定的。是否有种族条件导致我的想法失败
有谁知道更好的解决方案吗?尼廷·米达,你的想法是对的。这让我回到了我最初的尝试,对OnLostFocus进行了一点轻微的更改,就达到了目的:
protected override void OnLostFocus(RoutedEventArgs e)
{
base.OnLostFocus(e);
if (!IsChild(FocusManager.GetFocusedElement()))
{
HideToolbar();
}
}
GotFocus和LostFocus是使用气泡策略的RoutedEvents,因此家长也会捕获孩子的事件,所以为什么不直接处理家长的事件并采取适当的行动呢?我很感激这是几年前的事情,但我有完全相同的问题,但是在silverlight图书馆中找不到IsChild。。。你能详细说明一下吗?
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 { /**/ }
}