简体   繁体   English

UWP XAML弹出窗口不遵守VerticalAlignment吗?

[英]UWP XAML Popup not respecting VerticalAlignment?

I'm trying to center a Popup in a Windows Store/UWP app. 我正在尝试在Windows应用商店/ UWP应用中居中显示弹出窗口。

In brief, I'm taking MainPage and adding... 简而言之,我正在使用MainPage并添加...

  • A TextBlock with some text 带有一些文本的TextBlock
  • A Button with an event handler, Button_Click 具有事件处理程序的ButtonButton_Click
  • A Popup named popupTest . 一个名为popupTestPopup popupTest It contains... 它包含...
    • A Border with... 与...的Border
      • A StackPanel with 一个StackPanel
        • A TextBlock 一个TextBlock
        • A Button . 一个Button This Button 's event handle sets the Popup 's IsOpen to false. Button的事件句柄将PopupIsOpen为false。

Button_Click calls _centerPopup , which tries to center the Popup and then sets IsOpen to true . Button_Click调用_centerPopup ,它将尝试使Popup居中,然后将IsOpen设置为true I can't get this to work. 我无法使它正常工作。

private void _centerPopup(Popup popup, Border popupBorder, FrameworkElement extraElement = null)
{
    double ratio = .9; // How much of the window the popup fills, give or take. (90%)

    Panel pnl = (Panel)popup.Parent;
    double parentHeight = pnl.ActualHeight;
    double parentWidth = pnl.ActualWidth;

    // Min 200 for each dimension.
    double width = parentWidth * ratio > 200 ? parentWidth * ratio : 200;
    double height = parentHeight * ratio > 200 ? parentHeight * ratio : 200;

    popup.Width = width;
    popup.Height = height;

    //popup.HorizontalAlignment = HorizontalAlignment.Center;
    popup.VerticalAlignment = VerticalAlignment.Top;    // <<< This is ignored?!

    // Resize the border too. Not sure how to get this "for free".
    popupBorder.Width = width;
    popupBorder.Height = height;

    // Not using this here, but if there's anything else that needs resizing, do it.
    if (null != extraElement)
    {
        extraElement.Width = width;
        extraElement.Height = height;
    }
}

If I don't try to resize and center the Popup in Button_Click, here's what I get after clicking "Click Me"... 如果我不尝试在Button_Click中调整弹出窗口的大小并居中,这是单击“单击我”后得到的结果...

private void Button_Click(object sender, RoutedEventArgs e)
{
    //_centerPopup(this.popupTest, this.popupTestBorder);
    this.popupTest.IsOpen = true;
}

单击我单击,没有调整大小或居中

If I uncomment out the call to _ centerPopup , I get this, with the popup staying under the button: 如果取消注释对_ centerPopup的调用, centerPopup得到此提示,并且弹出窗口位于按钮下方

private void Button_Click(object sender, RoutedEventArgs e)
{
    _centerPopup(this.popupTest, this.popupTestBorder);
    this.popupTest.IsOpen = true;
}

随着重新定位和调整大小

That's no good. 不好 I thought popup.VerticalAlignment = VerticalAlignment.Top; 以为 popup.VerticalAlignment = VerticalAlignment.Top; would've fixed that. 会解决的。

FrameworkElement.VerticalAlignment Property FrameworkElement.VerticalAlignment属性

Gets or sets the vertical alignment characteristics applied to this element when it is composed within a parent element such as a panel or items control. 获取或设置在父元素(例如面板或项目控件)中组成该元素时应用于该元素的垂直对齐特性。


Move Popup to top of StackPanel? 将弹出窗口移到StackPanel的顶部?

Strangely, if I move the Popup up to the top of my StackPanel, it actually pushes the other controls down after being shown. 奇怪的是,如果我将Popup向上移动到StackPanel的顶部,它实际上会在显示后将其他控件下推。

Clicking "Click Me" without _centerPopup : 单击不带 _centerPopup “单击我”:

看起来很有希望

That looks promising! 看起来很有希望! It's floating over the other controls nicely, and there's no obvious impact to the layout after it's closed. 它很好地悬浮在其他控件上,并且在关闭后对布局没有明显影响。

But add back _centerPopup , even after commenting out setting VerticalAlignment to Top , and things die a horrible, fiery death. 但是即使在注释掉将VerticalAlignment设置为Top之后,也要添加_centerPopup ,事情会死于可怕的,致命的死亡。

下推控件

It looks perfect until you notice that every other control was pushed down . 除非您注意到所有其他控件都被按下,否则它看起来很完美。 ??? ??? Here's after clicking "Click to close": 点击“点击关闭” 后,这里的:

东西被永久压低

Other controls are pushed down permanently . 其他控件将永久按下。 Why does that happen? 为什么会这样呢? Shouldn't the popup float like it did before I resized it? 弹出窗口大小不应该像我调整大小之前那样吗?


Full Source 完整资料

XAML XAML

<Page
    x:Class="PopupPlay.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PopupPlay"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel Name="StackMain">
        <TextBlock>
            This is some text<LineBreak />
            This is some text<LineBreak />
            This is some text<LineBreak />
            This is some text<LineBreak />
        </TextBlock>
        <Button Click="Button_Click" Content="Click Me"></Button>

        <Popup x:Name="popupTest">
            <Border
                    Name="popupTestBorder"
                    Background="{StaticResource ApplicationPageBackgroundThemeBrush}"
                    BorderBrush="{StaticResource ApplicationForegroundThemeBrush}"
                    BorderThickness="2">
                <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                    <TextBlock Name="txtPopup"
                               Text="This is some text"
                               FontSize="24"
                               HorizontalAlignment="Center" />
                    <Button Name="btnClose"
                            Click="btnClose_Click"
                               Content="Click to close"></Button>
                </StackPanel>
            </Border>
        </Popup>
    </StackPanel>
</Page>

Full MainPage.xaml.cs code 完整的MainPage.xaml.cs代码

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;

namespace PopupPlay
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            _centerPopup(this.popupTest, this.popupTestBorder);

            this.popupTest.IsOpen = true;
        }

        private void _centerPopup(Popup popup, Border popupBorder, FrameworkElement extraElement = null)
        {
            double ratio = .9; // How much of the window the popup fills, give or take. (90%)

            Panel pnl = (Panel)popup.Parent;
            double parentHeight = pnl.ActualHeight;
            double parentWidth = pnl.ActualWidth;

            // Min 200 for each dimension.
            double width = parentWidth * ratio > 200 ? parentWidth * ratio : 200;
            double height = parentHeight * ratio > 200 ? parentHeight * ratio : 200;

            popup.Width = width;
            popup.Height = height;

            //popup.HorizontalAlignment = HorizontalAlignment.Center;
            popup.VerticalAlignment = VerticalAlignment.Top;    // <<< This is ignored?!

            // Resize the border too. Not sure how to get this "for free".
            popupBorder.Width = width;
            popupBorder.Height = height;

            // Not using this here, but if there's anything else that needs resizing, do it.
            if (null != extraElement)
            {
                extraElement.Width = width;
                extraElement.Height = height;
            }
        }

        private void btnClose_Click(object sender, RoutedEventArgs e)
        {
            this.popupTest.IsOpen = false;
        }
    }
}

There are several questions that seem related. 似乎有几个相关的问题。 I do not see a viable fix. 我看不到可行的解决方案。 (Note: These are not all UWP specific.) (注意:这些并不都是特定于UWP的。)

Painfully, this same setup is working for me in another app when it's positioned in a much more complicated grid with a Pivot, but I see that pivots are buggy . 痛苦的是,当该应用程序位于带有Pivot的更为复杂的网格中时,该设置也可以在另一个应用程序中为我工作,但我发现透视表有问题

Wpf's Placement stuff sounds promising , but doesn't exist in UWP-land. Wpf的Placement 听起来很有希望 ,但在UWP领域并不存在。

Your Popup is inside a vertical StackPanel , which means the StackPanel will lay out the popup alongside the other child elements of the panel, which is why it pushes down the text. 您的Popup窗口位于垂直的StackPanel内部,这意味着StackPanel将在面板的其他子元素旁边放置弹出窗口,这就是为什么向下推文本的原因。

Also, the VerticalAlignment is being ignored by the panel because the panel allocated exactly enough vertical space for the popup's size, and so there is no room for it to align the popup vertically within the space it was allocated. 而且,面板会忽略VerticalAlignment ,因为面板为弹出窗口的大小分配了足够的垂直空间,因此没有空间将弹出窗口在分配的空间内垂直对齐。

I would suggest using a Grid as the root element for the Page , and putting the StackPanel and Popup directly inside the Grid , like this: 我建议使用Grid作为Page的根元素,然后将StackPanelPopup直接放在Grid内部,如下所示:

<Grid>
    <StackPanel Name="StackMain">
        <TextBlock>
        This is some text<LineBreak />
        This is some text<LineBreak />
        This is some text<LineBreak />
        This is some text<LineBreak />
        </TextBlock>
        <Button Click="Button_Click" Content="Click Me"></Button>
    </StackPanel>
    <Popup x:Name="popupTest">
        <Border
                Name="popupTestBorder"
                Background="{StaticResource ApplicationPageBackgroundThemeBrush}"
                BorderBrush="{StaticResource ApplicationForegroundThemeBrush}"
                BorderThickness="2">
            <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                <TextBlock Name="txtPopup"
                           Text="This is some text"
                           FontSize="24"
                           HorizontalAlignment="Center" />
                <Button Name="btnClose"
                        Click="btnClose_Click"
                           Content="Click to close"></Button>
            </StackPanel>
        </Border>
    </Popup>
</Grid>

Grid s are good for this purpose, when you want to have overlapping elements or multiple elements that do not affect the position and size of any other child element. 当您希望有重叠的元素或不影响任何其他子元素的位置和大小的多个元素时, Grid就是很好的选择。 You want the layout of the popup to be separate from the layout of the stack panel and its children, so you should organize your XAML as such. 您希望弹出窗口的布局与堆栈面板及其子级的布局分开 ,因此您应该这样组织XAML。

Try changing your xaml as follows... 尝试如下更改您的xaml ...

<Page...>
    <Grid x:Name="LayoutRoot">
        <Popup>
        </Popup>

        <Grid x:Name="ContentPanel">
        </Grid>
    </Grid>
</Page>

So move the Popup control outside the content area and put your stacklayout with all content inside the ContentPanel Grid ( as shown in code sample above ) 因此,将Popup控件移到内容区域之外,然后将所有内容放入您的stacklayout到ContentPanel网格中(如上面的代码示例所示)

That should stop pushing the other controls down... 那应该停止向下推其他控件...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM