У меня есть всплывающее окно, которое заполнит всю страницу при открытии.

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

Всплывающее окно является UserControl

<Grid Background="Red">
    <Button Content="Close" HorizontalAlignment="Center" Click="{x:Bind viewModel.ClosePopup}" />
</Grid>
  1. Страница

enter image description here

  1. Когда отображается всплывающее окно

enter image description here

  1. Закройте всплывающее окно, измените размер страницы, затем снова откройте всплывающее окно. Обратите внимание, что он не соответствует новому размеру страницы контейнера, хотя его Width и Height привязаны к gridRoot. Нужно ли вручную устанавливать новые Width и Height для всплывающего окна? Почему я не могу достичь этого с помощью привязки? Эта проблема также появляется на мобильном телефоне во время OrientationChanged

enter image description here

3
PutraKg 19 Мар 2017 в 07:16

2 ответа

Лучший ответ

Основываясь на комментарии Десятилетия Луны, это, как изменить размер всплывающего окна, чтобы соответствовать родительскому контейнеру, поскольку его размер изменился.

Создайте свойство зависимости в коде

    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>

Довольно прямо вперед. Только не забудьте использовать свойства ActualWidth или ActualHeight для источника привязки как они не вызывают событие PropertyChanged.

Хотя оно имеет вспомогательное поле ActualWidthProperty, ActualWidth не вызывает уведомлений об изменении свойств, и его следует рассматривать как обычное свойство CLR, а не свойство зависимости.

В целях связывания ElementName ActualWidth не публикует обновления при его изменении (из-за асинхронного и вычисляемого характера во время выполнения). Не пытайтесь использовать ActualWidth в качестве источника привязки для привязки ElementName. Если у вас есть сценарий, который требует обновлений на основе ActualWidth, используйте обработчик SizeChanged.

1
PutraKg 20 Мар 2017 в 02:19

У @PutraKg отличный способ.

Но у меня есть два способа решить это.

Первый - это VerticalAlignment="Center" HorizontalAlignment="Center", который может сделать всплывающее окно в центре.

Но я думаю, что вы не можете поставить его в центр.

Отличный способ - использовать положение экрана.

Вы можете получить положение экрана сетки и сделать его всплывающим.

В открытой кнопке

    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;
    }
1
lindexi 20 Мар 2017 в 02:52