WPF Popup总是置顶,遮挡其他窗口的问题

2016-11-17 19:06:25来源:CSDN作者:wcc27857285人点击

最近发现popup设置打开后,总是会遮挡其他窗口,而我们只想让它仅仅在应用程序的上一层即可,并不像让它在最上面

解决方案是继承Popup重新定义控件PopupEx。

public class PopupEx : Popup
    {
        public static DependencyProperty TopmostProperty = Window.TopmostProperty.AddOwner(typeof(PopupEx ), 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 PopupEx ).UpdateWindow();
        }
        protected override void OnOpened(EventArgs e)
        {
            UpdateWindow();
        }
        private void UpdateWindow()
        {
            var hwnd = ((HwndSource)PresentationSource.FromVisual(this).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 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
    }

然后在调用该控件的时候设置该PopupEx的属性 Topmost=False即可。


以上方法来自 Leaco 的博客:http://www.cnblogs.com/Leaco


但是,呵呵,然并软,在new该popupEx的时侯设置topmost=false之后,还是会置顶

后来再加上了一句代码即可解决这个问题:就是在将popupEx加入到某个panel或者父容器当中,因为popup的parent的只读的,无法赋值,

所以我就让一个dockpanel.Children.Add(popupEx),配合PopupEx类,就完美解决了该问题。


************2016.11.16******************************

但是这个popup随着窗体移动不会消失,网上流传的方法就是在主窗体的locationchanged事件和sizechanged事件里面

回调一个函数,代码如下:

  Loaded += (sender, e) =>
              {
                  Window window = Window.GetWindow(this);
                  window.LocationChanged += HandleMovePopup;
                  window.SizeChanged += HandleMovePopup;
              };

 void HandleMovePopup(object sender, EventArgs e)
        {
            if (NewMsgPop != null && NewMsgPop.IsOpen)
            {
                var mi = typeof(Popup).GetMethod("UpdatePosition", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                mi.Invoke(NewMsgPop, null);
            }
        }
是可以解决这个移动窗体的问题。然并软,还有更坑爹的事情,当程序不在最顶部,既有其他应用程序在最顶部时,

让popup.isopen=true时,还是会显示在其他应用程序之前。。。。。。。。。。

真是欲哭无泪,最后的解决方案是:改成一个label, 通过设置Gird.SetZindex(label,0)或者Gird.SetZindex(label,2)来控制label的显隐。

前提是将label放进一个Grid里面

至此,这个功能需求算是圆满完成了,留给我的启发是,以后能不用popup尽量不用。。。。。。。


当然肯定有办法能解决这个问题,迫于项目压力,没有时间去细究,

当然如果有高人能说出更厉害的方法来解决这个问题,希望能赐教!

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台