WPF Popup 相关内容
引自:http://technet.microsoft.com/zh-cn/magazine/bb613596(VS.90).aspx
http://www.th7.cn/Program/WPF/201307/142902.shtml
http://www.th7.cn/Program/WPF/201307/141820.shtml
1、Popup弹出的位置
相关属性:Placement,PlacementTarget。具体看http://technet.microsoft.com/zh-cn/magazine/bb613596(VS.90).aspx
2、popup始终置顶的问题
只要设置Popup的StayOpen为true,则popup始终显示在桌面的最顶层,解决方法参考:http://www.th7.cn/Program/WPF/201307/141820.shtml,自定义CustomPopup
public class CustomPopup : Popup { public static DependencyProperty TopmostProperty = Window.TopmostProperty.AddOwner(typeof(CustomPopup), 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 CustomPopup).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的拖动功能
参考:http://www.th7.cn/Program/WPF/201307/142902.shtml
后台代码:其中PopupMouseDown是Popup内部一个Grid的MousLeftButtonDown事件的处理方法,xmal代码就不贴了。
[DllImport("user32.dll")] public static extern IntPtr WindowFromPoint(POINT Point); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetCursorPos(out POINT lpPoint); [DllImportAttribute("user32.dll")] public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); [DllImportAttribute("user32.dll")] public static extern bool ReleaseCapture(); [StructLayout(LayoutKind.Sequential)] public struct POINT { public int X; public int Y;} public const int WM_NCLBUTTONDOWN = 0xA1; public const int HT_CAPTION = 0x2; private void PopupMouseDown(object sender, MouseButtonEventArgs e) { POINT curPos; IntPtr hWndPopup; GetCursorPos(out curPos); hWndPopup = WindowFromPoint(curPos); ReleaseCapture(); SendMessage(hWndPopup, WM_NCLBUTTONDOWN, new IntPtr(HT_CAPTION), IntPtr.Zero); }
4、Popup不随窗体移动
参考:http://stackoverflow.com/questions/1600218/how-to-move-a-wpf-popup
http://social.msdn.microsoft.com/Forums/zh-CN/wpfzhchs/thread/2616e607-3954-4bfd-ae29-e0d813263030
方法很多,具体看上面2个,这里推荐2种:
注册窗体的LocationChanged事件:
public MainWindow() { LocationChanged += new EventHandler(MainWindow_LocationChanged); }
在事件处理方法中:
void MainWindow_LocationChanged(object sender, EventArgs e) { //方法1 var mi = typeof(Popup).GetMethod("UpdatePosition", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); mi.Invoke(popBottom, null); //方法2 //popBottom.ClearValue(Popup.IsOpenProperty); //popBottom.IsOpen = true; }