Home > WPF, WPF Controls > Making WPF Popups Work in Windowless Applications

Making WPF Popups Work in Windowless Applications

September 23rd, 2009

I’ve first encountered this issue with my WPF NotifyIcon, and now again while writing a plug-in for Windows Live Writer: If you try to display a WPF popup without any Windows open (the Popup is the only UI component there is), certain controls such as TextBox, ListView, or ListBox don’t receive proper mouse and/or keyboard input, and cannot be selected.

The reason for this issue is buried in the WPF framework, and how it interacts with Windows. Fellow WPF Disciple Andrew Smith pointed me in the right direction:

 

…because a Popup’s HWND has the WS_EX_NOACTIVATE so the WPF framework will not attempt to actually focus the associated hwnd (because its usually used with a window and you don’t want to deactivate the window when you focus something in the popup).

 

Accordingly, you’ll have to fiddle with Windows Interop to make things work. Here’s the snippet:

 

public static class WinApi
{
  /// <summary>
  /// Gives focus to a given window.
  /// </summary>
  [DllImport("USER32.DLL")]
  public static extern bool SetForegroundWindow(IntPtr hWnd);


  public static void ActivatePopup(Popup popup)
  {
    //try to get a handle on the popup itself (via its child)
    HwndSource source = (HwndSource)PresentationSource.FromVisual(popup.Child);
    IntPtr handle = source.Handle;

    //activate the popup
    SetForegroundWindow(handle);
  }
}

Author: Categories: WPF, WPF Controls Tags:
  1. October 23rd, 2009 at 16:15 | #1

    Philipp, I wonder why you have created the created the icon class based on FrameworkElement? Changing the ancestor to ‘Control’ does not impact the control functionality but does allow it to be styled. Maybe I’ve missed how the icon and its attibutes can be set any way other than in-line.

    My requirement was to have a windowless control in a WinForms environment(the example you provide still has a window). In my case I want the control to be genuinely windowless. One way to do this is to instantiate a WPF UserControl which contains markup to include the tray icon control. However then all the events and properties have to be replicated in the UserControl.

    By changing the notify icon control to inherit from ‘Control’ it becomes possible to define a style for the notify icon control without additional wrappers.

    You can download an example project here:

    http://s3downloads.lyquidity.com/WindowlessSample.zip

    It assumes you’ve changed the inheritance of TaskbarIcon

    It also relies on a method I’ve added to my copy of the code to load a style. In a WinForms app there is no App or Window instance so styles do not get applied automatically. Instead this three line method loads a Xaml resource dictionary file and applies the style.

    public void StyleFromXamlResourceDictionary(string dict)
    {
    ResourceDictionary rd = Application.LoadComponent(new Uri(dict, UriKind.Relative)) as ResourceDictionary;
    if (rd == null) return;
    this.Resources.MergedDictionaries.Add(rd);
    }

    The string ‘dict’ is a uri to a resource dictionary such as:

    /MyApp;component/MyResources/NotifyIconStyle.xaml

  1. August 1st, 2013 at 16:06 | #1