Silverlight popup ActualSize

时间:2009-07-29 20:58:03

标签: c# silverlight xaml silverlight-3.0

在Silverlight 3中,我正在尝试创建一个用于导航的弹出菜单。我使用HyperlinkBut​​ton作为触发器,当moused显示包含更多HyperlinkBut​​tons的Popup时。根节点右对齐,我希望子菜单显示在左侧。我的问题是我试图使用其ActualWidth属性来定位弹出窗口,但是这个值看起来固定在根元素的大小(包含触发器和弹出窗口),因此如果弹出窗口较窄则会留下难看的间隙,如果更宽,它会覆盖触发器。

这是我的XAML:

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.Resources>
        <Style x:Key="MenuItemStyle" TargetType="HyperlinkButton">
            <Setter Property="Background" Value="Blue" />
            <Setter Property="Foreground" Value="White" />
            <Setter Property="HorizontalContentAlignment" Value="Center" />
        </Style>
    </Grid.Resources>

    <Grid x:Name="Root" HorizontalAlignment="Right" VerticalAlignment="Top">
        <HyperlinkButton 
            x:Name="hl"  
            Style="{StaticResource MenuItemStyle}"
            MouseEnter="hl_MouseEnter" MouseLeave="hl_MouseLeave">
            <HyperlinkButton.Content>
                <Grid>
                    <TextBlock Text="MenuRoot" />
                </Grid>
            </HyperlinkButton.Content>
        </HyperlinkButton>

        <Popup x:Name="p">
            <Popup.Child>
                <HyperlinkButton 
                    Style="{StaticResource MenuItemStyle}">
                    <HyperlinkButton.Content>
                        <StackPanel>
                            <TextBlock Text="Sub" />
                        </StackPanel>
                    </HyperlinkButton.Content>
                </HyperlinkButton>
            </Popup.Child>
        </Popup>
    </Grid>
</Grid>

和我的代码:

    private void hl_MouseEnter(object sender, MouseEventArgs e)
    {
        p.HorizontalOffset = -p.ActualWidth;
        p.IsOpen = true;
    }

    private void hl_MouseLeave(object sender, MouseEventArgs e)
    {
        p.IsOpen = false;
    }

我尝试使用弹出窗口的子宽度,但在MouseEnter事件期间设置为0,因为它是隐藏的。

我是Silverlight的新手,所以任何帮助都会受到赞赏。

1 个答案:

答案 0 :(得分:5)

Popup展开以填充网格列,但Popup的内容实际上并未在Popup显示之后进行测量和定位。您可以通过命名Hyperlink的内容来解决此问题。假设内部Hyperlink名为s。然后,您可以将事件处理程序修改为:

private void hl_MouseEnter(object sender, MouseEventArgs e)
{
  p.IsOpen = true;
  p.UpdateLayout();
  p.HorizontalOffset = -s.ActualWidth;
}

在致电UpdateLayout后,内部Hyperlink的内容自然为Popup

不幸的是,只要鼠标离开父HyperlinkHyperlink就会关闭,因此无法点击子{{1}}。