Как убедиться, что элемент управления Popup соответствует родительской странице при изменении размера родителя? UWP

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

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

Всплывающее окно - это пользовательский элемент управления

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

введите здесь описание изображения

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

введите здесь описание изображения

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

введите здесь описание изображения


person PutraKg    schedule 19.03.2017    source источник
comment
Может использовать положение мыши?   -  person lindexi    schedule 19.03.2017
comment
Можете ли вы уточнить?   -  person PutraKg    schedule 19.03.2017
comment
Установка ActualWidth в качестве источника привязки обычно не работает должным образом. См. это для получения дополнительной информации.   -  person Decade Moon    schedule 19.03.2017
comment
В контексте вашего приложения, можете ли вы обойтись без использования Flyout и установить свойство PlacementMode=Full?   -  person Lindsay    schedule 21.03.2017
comment
@Lindsay, к сожалению, нет, потому что у меня есть несколько всплывающих окон, каждое из которых содержит разные элементы управления и функции.   -  person PutraKg    schedule 21.03.2017


Ответы (2)


Основываясь на комментарии 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>

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

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

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

person PutraKg    schedule 20.03.2017

У @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;
    }
person lindexi    schedule 20.03.2017
comment
Да, я не хочу просто размещать всплывающее окно в центре. К сожалению, для этого решения всплывающее окно соответствует родительскому контейнеру только при щелчке. Когда родительский элемент изменяется во время открытия всплывающего окна, он не будет изменяться автоматически. Спасибо за предложения в любом случае. - person PutraKg; 20.03.2017