如何在窗口中居中弹出窗口(Windowsapp store应用)

我有一个自定义弹出窗口(作为用户控件),我以编程方式加载。 我无法将其居中于x轴,仅在垂直方向上居中。 弹出窗口未添加到xaml文件中,但会在根窗口中添加。

using System; using System.Collections.Generic; using System.IO; using System.Linq; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; using System.Windows; using Windows.UI.Core; // The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236 namespace QSTLibrary.WIN8.Tools { public sealed partial class CustomProgressRingPopup : UserControl { public CustomProgressRingPopup() { this.InitializeComponent(); } public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } } // Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc... public static readonly DependencyProperty TextProperty = DependencyProperty.Register( "Text", typeof(string), typeof(CustomProgressRingPopup), new PropertyMetadata("", OnTextChanged)); public void OpenPopup() { this.ParentPopup.IsOpen = true; } public void ClosePopup() { this.ParentPopup.IsOpen = false; } private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var instance = d as CustomProgressRingPopup; var newValue = e.NewValue as string; if (instance != null && newValue != null) { instance.CustomTextBlock.Text = newValue; } } private void OnPopupLoaded(object sender, RoutedEventArgs e) { this.ParentPopup.HorizontalOffset = (Window.Current.Bounds.Width - gdChild.ActualWidth) / 2; this.ParentPopup.VerticalOffset = (Window.Current.Bounds.Height - gdChild.ActualHeight) / 2; } } } 

userControl xaml:

                

以下是我在外部使用它的方法:

 _loginProgressRingPopup.Text = "Logging in"; _loginProgressRingPopup.OpenPopup(); 

我已经在cs文件中添加了弹出窗口的LayoutUpdate回调,现在可以使用了。

 private void OnLayoutUpdated(object sender, object e) { if(gdChild.ActualWidth == 0 && gdChild.ActualHeight == 0) { return; } double ActualHorizontalOffset = this.ParentPopup.HorizontalOffset; double ActualVerticalOffset = this.ParentPopup.VerticalOffset; double NewHorizontalOffset = (Window.Current.Bounds.Width - gdChild.ActualWidth) / 2; double NewVerticalOffset = (Window.Current.Bounds.Height - gdChild.ActualHeight) / 2; if (ActualHorizontalOffset != NewHorizontalOffset || ActualVerticalOffset != NewVerticalOffset) { this.ParentPopup.HorizontalOffset = NewHorizontalOffset; this.ParentPopup.VerticalOffset = NewVerticalOffset; } } 

和XAML的弹出窗口:

  

Popup窗口放置在UWP Windowsapp store应用中并不是那么简单。 这是我最终解决它的方式。 不要观察LayoutUpdated事件(可能导致布局周期),而是观察视图顶级元素的SizeChanged事件,并使用它来重新定位它所包含的弹出窗口。

在我的例子中,我将对话框放在窗口的中心,因此使用Window.Current 。 您还需要转换坐标,因为弹出窗口将根据Popup元素在布局中实际定义的位置使用自己的相对坐标系:

 private void MyDialog_SizeChanged(object sender, SizeChangedEventArgs e) { var transform = Window.Current.Content.TransformToVisual(_popup); Point point = transform.TransformPoint(new Point(0, 0)); // gets the window's (0,0) coordinate relative to the popup double hOffset = (Window.Current.Bounds.Width - this.ActualWidth) / 2; double vOffset = (Window.Current.Bounds.Height - this.ActualHeight) / 2; _popup.HorizontalOffset = point.X + hOffset; _popup.VerticalOffset = point.Y + vOffset; } 

你可以在XAML文件中居中:

  

我修改了Butzke的答案,使其更具普遍性: