UWP XAML 弹出窗口不遵守 VerticalAlignment?
UWP XAML Popup not respecting VerticalAlignment?
我正在尝试将 Windows Store/UWP 应用程序中的弹出窗口居中。
简而言之,我正在使用 MainPage 并添加...
- A
TextBlock
带有一些文字
- 带有事件处理程序的
Button
,Button_Click
- 一个名为
popupTest
的 Popup
。它包含...
- 一个
Border
与...
- 一个
StackPanel
与
- 一个
TextBlock
- 一个
Button
。此 Button
的事件句柄将 Popup
的 IsOpen
设置为 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 中调整弹出窗口的大小和居中,这就是我在单击“单击我”后得到的...
private void Button_Click(object sender, RoutedEventArgs e)
{
//_centerPopup(this.popupTest, this.popupTestBorder);
this.popupTest.IsOpen = true;
}
如果我取消对 _centerPopup
的调用的注释,我会得到这个,弹出窗口位于 按钮下方:
private void Button_Click(object sender, RoutedEventArgs e)
{
_centerPopup(this.popupTest, this.popupTestBorder);
this.popupTest.IsOpen = true;
}
那可不行。我 thought popup.VerticalAlignment = VerticalAlignment.Top;
会解决这个问题。
FrameworkElement.VerticalAlignment Property
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.
将 Popup 移动到 StackPanel 的顶部?
奇怪的是,如果我将 Popup 移到 StackPanel 的顶部,它实际上会在显示后将其他控件向下推。
单击“单击我”没有 _centerPopup
:
看起来很有希望!它很好地悬浮在其他控件之上,关闭后对布局没有明显影响。
但是添加回来 _centerPopup
,即使在将设置 VerticalAlignment
注释掉到 Top
之后,事情也会死得很惨烈。
看起来很完美直到您注意到所有其他控件都被按下。 ???这里是在点击“点击关闭”之后:
其他控件永久下推。为什么会这样?弹出窗口不应该像我调整大小之前那样浮动吗?
完整来源
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>
完整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;
}
}
}
有几个问题似乎相关。我看不到可行的修复方法。 (注意:这些并不是所有 UWP 特定的。)
- Center Popup in XAML
- Place Popup at top right corner of a window in XAML
- How to set vertical offset for popup having variable height
痛苦的是,同样的设置在另一个应用程序中对我有用,当它被定位在一个带有 Pivot 的更复杂的网格中时,但我看到 pivots are buggy。
Wpf 的 Placement
内容 sounds promising,但在 UWP 领域中不存在。
尝试如下更改您的 xaml...
<Page...>
<Grid x:Name="LayoutRoot">
<Popup>
</Popup>
<Grid x:Name="ContentPanel">
</Grid>
</Grid>
</Page>
因此,将 Popup 控件移到内容区域之外,并将包含所有内容的 stacklayout 放在 ContentPanel Grid 中(如上面的代码示例所示)
应该停止将其他控件向下推...
您的 Popup
在垂直 StackPanel
内,这意味着 StackPanel
会将弹出窗口与面板的其他子元素并排放置,这就是它向下推的原因文本。
此外,VerticalAlignment
被面板忽略,因为面板为弹出窗口的大小分配了足够的垂直 space,因此没有空间让它垂直对齐弹出窗口space 它被分配了。
我建议使用 Grid
作为 Page
的根元素,并将 StackPanel
和 Popup
直接放在 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。
我正在尝试将 Windows Store/UWP 应用程序中的弹出窗口居中。
简而言之,我正在使用 MainPage 并添加...
- A
TextBlock
带有一些文字 - 带有事件处理程序的
Button
,Button_Click
- 一个名为
popupTest
的Popup
。它包含...- 一个
Border
与...- 一个
StackPanel
与- 一个
TextBlock
- 一个
Button
。此Button
的事件句柄将Popup
的IsOpen
设置为 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 中调整弹出窗口的大小和居中,这就是我在单击“单击我”后得到的...
private void Button_Click(object sender, RoutedEventArgs e)
{
//_centerPopup(this.popupTest, this.popupTestBorder);
this.popupTest.IsOpen = true;
}
如果我取消对 _centerPopup
的调用的注释,我会得到这个,弹出窗口位于 按钮下方:
private void Button_Click(object sender, RoutedEventArgs e)
{
_centerPopup(this.popupTest, this.popupTestBorder);
this.popupTest.IsOpen = true;
}
那可不行。我 thought popup.VerticalAlignment = VerticalAlignment.Top;
会解决这个问题。
FrameworkElement.VerticalAlignment Property
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.
将 Popup 移动到 StackPanel 的顶部?
奇怪的是,如果我将 Popup 移到 StackPanel 的顶部,它实际上会在显示后将其他控件向下推。
单击“单击我”没有 _centerPopup
:
看起来很有希望!它很好地悬浮在其他控件之上,关闭后对布局没有明显影响。
但是添加回来 _centerPopup
,即使在将设置 VerticalAlignment
注释掉到 Top
之后,事情也会死得很惨烈。
看起来很完美直到您注意到所有其他控件都被按下。 ???这里是在点击“点击关闭”之后:
其他控件永久下推。为什么会这样?弹出窗口不应该像我调整大小之前那样浮动吗?
完整来源
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>
完整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;
}
}
}
有几个问题似乎相关。我看不到可行的修复方法。 (注意:这些并不是所有 UWP 特定的。)
- Center Popup in XAML
- Place Popup at top right corner of a window in XAML
- How to set vertical offset for popup having variable height
痛苦的是,同样的设置在另一个应用程序中对我有用,当它被定位在一个带有 Pivot 的更复杂的网格中时,但我看到 pivots are buggy。
Wpf 的 Placement
内容 sounds promising,但在 UWP 领域中不存在。
尝试如下更改您的 xaml...
<Page...>
<Grid x:Name="LayoutRoot">
<Popup>
</Popup>
<Grid x:Name="ContentPanel">
</Grid>
</Grid>
</Page>
因此,将 Popup 控件移到内容区域之外,并将包含所有内容的 stacklayout 放在 ContentPanel Grid 中(如上面的代码示例所示)
应该停止将其他控件向下推...
您的 Popup
在垂直 StackPanel
内,这意味着 StackPanel
会将弹出窗口与面板的其他子元素并排放置,这就是它向下推的原因文本。
此外,VerticalAlignment
被面板忽略,因为面板为弹出窗口的大小分配了足够的垂直 space,因此没有空间让它垂直对齐弹出窗口space 它被分配了。
我建议使用 Grid
作为 Page
的根元素,并将 StackPanel
和 Popup
直接放在 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。