关于popup的一些问题
整理了一些WPF popup常见的问题和解决方案:
基础的使用:
>Popup.StaysOpen属性:
设置为True,并且Popup控件会一直显示,直到显式地将IsOpen属性设置为False。
设置为False,当用户在其他地方单击鼠标时,Popup控件就会消失。
>IsOpen属性:
设置为True时,通过Popup控件的PopupAnimation属性可以设置Popup控件的显示方式。
>Popup控件不和任何控件相关联,所以无论在哪定义Popup标签都无所谓。
关联控件可以这样:
PlacementTarget="{Binding ElementName=button1}" //绑定在哪个控件上,这里是和button1这个控件绑定
Placement="Bottom"
1、用placement设置popup位置,却发现无效。
原因是Popup对齐位置还受到系统一个参数 SystemParameters.MenuDropAlignment影响,如果这个值为True 则就会发生你的那种情况。所以我们把这个系统参数改成False
[DllImport("user32.dll", EntryPoint = "SystemParametersInfo", SetLastError = true)]
public static extern bool SystemParametersInfoSet(uint action, uint uiParam, uint vparam, uint init);
...
SystemParametersInfoSet(0x001C /*SPI_SETMENUDROPALIGNMENT*/, 0, 0, 0);
2、popup中弹出MessageBox或者打开对话框的时候,popup总是置顶,并遮住MessageBox或对话框.解决方式是自己重写popup:
using System.Windows.Controls.Primitives;
using System.Runtime.InteropServices;
using System.Windows.Interop;
public class CCPopup : Popup
{
public static DependencyProperty TopmostProperty = Window.TopmostProperty.AddOwner(typeof(CCPopup), new FrameworkPropertyMetadata(false, OnTopmostChanged));
public bool Topmost
{
get { return (bool)GetValue(TopmostProperty); }
set { SetValue(TopmostProperty, value); }
}
private static void OnTopmostChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
(obj as CCPopup).UpdateWindow();
}
protected override void OnOpened(EventArgs e)
{
UpdateWindow();
}
private void UpdateWindow()
{
var hwnd = ((HwndSource)PresentationSource.FromVisual(this.Child)).Handle;
RECT rect;
if (GetWindowRect(hwnd, out rect))
{
SetWindowPos(hwnd, Topmost ? -1 : -2, rect.Left, rect.Top, (int)this.Width, (int)this.Height, 0);
}
}
#region P/Invoke imports & definitions
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32", EntryPoint = "SetWindowPos")]
private static extern int SetWindowPos(IntPtr hWnd, int hwndInsertAfter, int x, int y, int cx, int cy, int wFlags);
#endregion
}
3、当popup的母窗体移动,且有一部分移出屏幕范围之外的时候,popup会停留在屏幕边缘,当母窗体移回屏幕范围之内后,popup会跟着一起移动,从而造成popup和初始位置不同。
还未解决。

浙公网安备 33010602011771号