I'm struggling with an issue that is related to my NotifyIcon control, and was hoping one of you could point me in the right direction.
First, in case you have KaXaml installed, you can look at the issue very easily. Just paste the following snipped into Kaxaml and try to select the TextBox control of the popup:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Popup IsOpen="True">
<Border Background="Blue" BorderThickness="2" Padding="20">
<StackPanel>
<Button Width="200" Height="24" Content="Clickable" />
<TextBox Width="200" Height="24" Text="Unselectable" />
</StackPanel>
</Border>
</Popup>
</Grid>
</Page>
...you will notice that the Button behaves like a regular button (you can click it), while the TextBox does not take focus: You can neither select nor edit the text. So something in Kaxaml doesn't quite work as one might expect. Unfortunately, it's not Kaxaml that's causing me headaches :)
However, if you paste that Popup in a Window in Visual Studio, everything works ok - at first. I succeeded to reproduce the issue in a WPF application, by setting the main window to invisible. In case you'd like to have a look at it yourself, I've created a simple project:
www.hardcodet.net/uploads/popuppains.zip
The background of this issue: My NotifyIcon supports interactive popups that can be displayed if the NotifyIcon in the Tray is clicked. But as there is no visible window (actually no regular WPF window at all), certain controls are being "disabled", while others work. I currently don't really have an idea how to tackle this issue without introducing major hacks (read: dummy windows) into the control, so I'd be glad for any ideas that could get me back on track :)
Thanks for your advice
Philipp
--
code hard - http://www.hardcodet.net
-Andrew
Yeah, it sounds like black magic. Probably is.
Haven't figured out how to apply it, yet. But won't give up easily :)
Thanks you so much for the hint - I think I have (or am close to) a working solution :)
Here's how the NotifyIcon looked before. Actually, I already used Interop to set the foreground to the NotifyIcon's own message sink. This was required in order to have the Popup close if the user clicked on the desktop or another application:
//open popup
TrayPopupResolved.IsOpen = true;
//activate the message window to track deactivation - otherwise, the popup
//does not close if the user clicks somewhere else
WinApi.SetForegroundWindow(messageSink.MessageWindowHandle);
What I tried now is setting the foreground to the popup's window handle itself. I couldn't get a handle of the popup itself, but of the popup's content. And this worked! Here's the updated snippet (currently with a fallback mechanism and probably redundant null checks):
//open popup
TrayPopupResolved.IsOpen = true;
IntPtr handle = IntPtr.Zero;
if (TrayPopupResolved.Child != null)
{
//try to get a handle on the popup itself (via its child)
HwndSource source = (HwndSource)PresentationSource.FromVisual(TrayPopupResolved.Child);
if (source != null) handle = source.Handle;
}
//if we don't have a handle for the popup, fall back to the message sink
if (handle == IntPtr.Zero) handle = messageSink.MessageWindowHandle;
//activate either popup or message sink to track deactivation.
//otherwise, the popup does not close if the user clicks somewhere else
WinApi.SetForegroundWindow(handle);
I'll have to do some testing before releasing, but it looks very promising so far! Remind me to buy you potentially deadly amounts of beer should we ever meet :)
Cheers,
Philipp
> -----Original Message-----
> From: wpf-di...@googlegroups.com [mailto:wpf-
> disc...@googlegroups.com] On Behalf Of Andrew
> Sent: Montag, 21. September 2009 14:41
> To: wpf-di...@googlegroups.com