首页 文章

UWP XAML Popup不尊重VerticalAlignment?

提问于
浏览
2

我正在尝试将Popup放在Windows Store / UWP应用程序中 .

简而言之,我正在使用MainPage并添加...

  • A TextBlock 带有一些文字

  • A Button 带有事件处理程序, Button_Click

  • A Popup 名为 popupTest . 它包含...

  • A Border 与......

  • A StackPanel with

  • A TextBlock

  • A Button . 这个 Button 的事件句柄将 PopupIsOpen 设置为false .

Button_Click 调用 _centerPopup ,尝试将 Popup 居中,然后将 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;
    }
}

如果我没有尝试在Button_Click中调整Popup的大小和中心,这就是我点击“Click Me”后得到的...

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

Click Me clicked, no resizing or centering

如果我取消注释_ centerPopup 的调用,我得到这个,弹出按钮保持在按钮下:

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

with recentering and resizing

那不好 . 我会解决这个问题 . [1476773_ popup.VerticalAlignment = VerticalAlignment.Top;

FrameworkElement.VerticalAlignment属性获取或设置在父元素(如面板或项控件)中组合时应用于此元素的垂直对齐特征 .


将Popup移动到StackPanel的顶部?

奇怪的是,如果我将Popup移动到我的StackPanel的顶部,它实际上会在显示后将其他控件向下推 .

单击"Click Me",不使用 _centerPopup

looks promising

看起来很有希望!它很好地浮动在其他控件上,并且在关闭后对布局没有明显的影响 .

但是,即使在将 VerticalAlignment 设置为 Top 之后,也要加上 _centerPopup ,事情会死于可怕的,火热的死亡 .

Pushes controls down

它看起来很完美 until you notice that every other control was pushed down . ???点击"Click to close"后点击:

stuff is pushed down permanently

其他控件永久按下 . 为什么会这样?弹出窗口不应该像我调整大小之前一样浮动吗?


完整来源

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

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

有几个问题似乎有关 . 我没有看到可行的解决办法 . (注意:这些并非都是特定于UWP的 . )

痛苦的是,这个相同的设置在另一个应用程序中为我工作时,它位于一个更复杂的网格中,带有一个Pivot,但我看到了pivots are buggy .

Wpf的 Placement 东西sounds promising,但在UWP-land中不存在 .

2 回答

  • 1

    你的 Popup 在一个垂直 StackPanel 里面,这意味着 StackPanel 会将弹出窗口与面板的其他子元素放在一起,这就是它推文的原因 .

    此外,面板会忽略 VerticalAlignment ,因为面板为弹出窗口的大小分配了足够的垂直空间,因此没有空间让弹出窗口在其分配的空间内垂直对齐 .

    我建议使用 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对此有用 . 您希望弹出窗口的布局与堆栈面板及其子窗体的布局分开,因此您应该像这样组织XAML .

  • 3

    尝试更改您的xaml如下...

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

    因此,将Popup控件移到内容区域之外,并将stacklayout与ContentPanel Grid中的所有内容放在一起(如上面的代码示例所示)

    这应该停止推动其他控件...

相关问题