Tutorial :WPF Popup ZOrder


I am using a WPF Popup, but it popups up above every single window on my desktop, even when my application is minimized. How can I make it stay only on the window it originated? The same thing happens when my window is behind other windows: the popup displays above them all.

"There must be something can be done!"



I've tried to solve this issue as well, and have found no good solution. This seems to be the way it is supposed to work, and you can't override that.

The only solution I've come up with is to just use a regular layout panel and raise it's Z-Index, so it is the top-level control (this sort of simulates the Popup). The only time I have found that this won't work is when you have WinForms on the screen through WindowsFormsHosts. Those Winforms are always at a higher Z-Index than any of the WPF stuff. That is when you have to use a Popup to get around it.


So I dug through the framework source code to see where it actually causes the window to be topmost and it does this in a private nested class. However, it does not provide an option to either just be a child popup of the main window or to be the topmost window. Here is a hack to make it always a child popup window. One could easily add a dependency property and do some more magic to make it the top most.

using System;  using System.Reflection;  using System.Windows;  using System.Windows.Controls.Primitives;    namespace UI.Extensions.Wpf.Controls  {      public class ChildPopup : Popup      {          static ChildPopup()          {              DefaultStyleKeyProperty.OverrideMetadata(typeof(ChildPopup), new FrameworkPropertyMetadata(typeof(ChildPopup)));          }            public ChildPopup()          {              Type baseType = this.GetType().BaseType;              dynamic popupSecHelper = GetHiddenField(this, baseType, "_secHelper");              SetHiddenField(popupSecHelper, "_isChildPopupInitialized", true);              SetHiddenField(popupSecHelper, "_isChildPopup", true);          }            protected dynamic GetHiddenField(object container, string fieldName)          {              return GetHiddenField(container, container.GetType(), fieldName);          }            protected dynamic GetHiddenField(object container, Type containerType, string fieldName)          {              dynamic retVal = null;              FieldInfo fieldInfo = containerType.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance);              if (fieldInfo != null)              {                  retVal = fieldInfo.GetValue(container);              }              return retVal;          }            protected void SetHiddenField(object container, string fieldName, object value)          {              SetHiddenField(container, container.GetType(), fieldName, value);          }            protected void SetHiddenField(object container, Type containerType, string fieldName, object value)          {              FieldInfo fieldInfo = containerType.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance);              if (fieldInfo != null)              {                  fieldInfo.SetValue(container, value);              }          }      }  }  


Check this: http://chriscavanagh.wordpress.com/2008/08/13/non-topmost-wpf-popup/

may be this can help you!!


Although I've not tried to do it, I've also read that this can be done using adorners...Matt Galbraith suggested it on the MSDN forum when asked the same question...in case anyone is still reading this thread.

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »