关于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和初始位置不同。

还未解决。

 

posted @ 2014-04-04 11:33  晴朗天空  阅读(779)  评论(0)    收藏  举报