如何在调整父级调整大小时确保Popup控件与其父页面匹配? UWP

时间:2017-03-19 04:16:30

标签: xaml popup uwp win-universal-app

我有一个Popup,它会在打开时填满整个页面。

<Grid x:Name="gridRoot" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Button Content="Open" HorizontalAlignment="Center" Click="{x:Bind viewModel.OpenPopup}" />
    <Popup x:Name="popupCorrect" VerticalAlignment="Top" IsOpen="{Binding IsOpen}" IsLightDismissEnabled="False">
        <Popup.ChildTransitions>
            <TransitionCollection>
                <PaneThemeTransition Edge="Left" />
            </TransitionCollection>
        </Popup.ChildTransitions>
        <uc:MyPopup  Width="{Binding ElementName=gridRoot, Path=ActualWidth}" Height="{Binding ElementName=gridRoot, Path=ActualHeight}"/>
    </Popup>
</Grid>

Popup是一个UserControl

<Grid Background="Red">
    <Button Content="Close" HorizontalAlignment="Center" Click="{x:Bind viewModel.ClosePopup}" />
</Grid>
  1. 页面
  2. enter image description here

    1. 显示弹出窗口时
    2. enter image description here

      1. 关闭弹出窗口,调整页面大小,然后重新打开弹出窗口。请注意,即使其WidthHeight绑定到gridRoot,它也与容器页面的新大小不匹配。我是否必须为弹出窗口手动设置新的WidthHeight?为什么我不能通过绑定实现这一目标?在“OrientationChanged”
      2. 期间,此问题也会出现在手机上

        enter image description here

2 个答案:

答案 0 :(得分:1)

根据Decade Moon评论,这是如何调整弹出窗口以匹配父容器,因为它的大小已更改。

背后的代码中创建依赖项属性
    public double PageWidth
    {
        get { return (double)GetValue(PageWidthProperty); }
        set { SetValue(PageWidthProperty, value); }
    }

    public static readonly DependencyProperty PageWidthProperty =
        DependencyProperty.Register("PageWidth", typeof(double), typeof(GamePage), new PropertyMetadata(0d));



    public double PageHeight
    {
        get { return (double)GetValue(PageHeightProperty); }
        set { SetValue(PageHeightProperty, value); }
    }

    public static readonly DependencyProperty PageHeightProperty =
        DependencyProperty.Register("PageHeight", typeof(double), typeof(GamePage), new PropertyMetadata(0d));

更新SizeChanged事件

上的值
    private void GamePage_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        if (e.NewSize.Width > 0d && e.NewSize.Height > 0d)
        {
            PageWidth = e.NewSize.Width;
            PageHeight = e.NewSize.Height;
        }
    }

然后在XAML中,只需使用x:Bind来绑定弹出框的宽度和高度

        <Popup x:Name="popupCorrect" VerticalAlignment="Top" IsOpen="{Binding IsPopupCorrectOpen, Mode=TwoWay}" IsLightDismissEnabled="False">
        <Popup.ChildTransitions>
            <TransitionCollection>
                <PaneThemeTransition Edge="Left" />
            </TransitionCollection>
        </Popup.ChildTransitions>
        <uc:PopupCorrect Width="{x:Bind PageWidth, Mode=TwoWay}" Height="{x:Bind PageHeight, Mode=TwoWay}"/>
    </Popup>

非常直接。请记住,不要将ActualWidthActualHeight属性用于绑定源they do not raise the PropertyChanged event

  

虽然它有一个ActualWidthProperty支持字段,但ActualWidth不会引发属性更改通知,它应该被视为常规CLR属性而不是依赖属性。

     

出于ElementName绑定的目的,ActualWidth在更改时不会发布更新(由于其异步和运行时计算的性质)。不要尝试使用ActualWidth作为ElementName绑定的绑定源。如果您的方案需要基于ActualWidth进行更新,请使用SizeChanged处理程序。

答案 1 :(得分:1)

@PutraKg有一个很好的方式。

但我有两种方法可以解决它。

第一个设置VerticalAlignment="Center" HorizontalAlignment="Center"可以使弹出窗口位于中心。

但我认为你不满足于把它放在中心。

最棒的方法是使用屏幕位置。

您可以获取Grid的屏幕位置并使其弹出。

在打开按钮

    private void Button_OnClick(object sender, RoutedEventArgs e)
    {
        var grid = (UIElement)popupCorrect.Parent; //get grid
        var p = grid.TransformToVisual (Window.Current.Content).TransformPoint(new Point(0, 0)); //get point
        popupCorrect.HorizontalOffset = p.X;
        popupCorrect.VerticalOffset = p.Y;
        popupCorrect.IsOpen = !popupCorrect.IsOpen;
    }