I used the above Answer but it seems to have a little bug on it.
The problem asserts itself only when the Popup is expanded (and StaysOpen=false).
Here is how you reproduce it:
- The user toggles the
ToggleButton (which expands the Popup)
- The user (accidentally) moves the mouse off the
ToggleButton.
- The user goes to toggle the
ToggleButton (to close the Popup manually)
At this point, the Popup collapses, and then immediately expands (the same symptoms as the original symptoms above).
Here is what is happening:
If you have StaysOpen set to false, the Popup internally captures the mouse (so that it knows if the user has clicked elsewhere … so that it can collapse the Popup).
However, what that does is causes us not to get the MouseEnter above (and thus the necessary and needed StaysOpen=true behavior for manually toggling the Popup open and closed).
Therefore, when the user goes to toggle the Popup closed manually (step 3 above), the captured mouse tells the Popup to collapse … however, then the ToggleButton kicks in and re-toggles the Popup open.
Here is the solution:
You need to make the ToggleButton not respond to the mouse when the Popup is expanded. In this way, only the StaysOpen=false, mouse capture functionality kicks in … and the Popup collapses … and doesn’t expand again.
How do you do this? You need to bind the IsHitTestVisible property of the ToggleButton to the !IsOpen property of the Popup.
To get the !IsOpen (Inverted IsOpen Value) you need to use a IValueConverter.
Here is the resulting Code:
1. XAML
<ToggleButton
Name="TestButton"
Width="100"
Height="28"
IsHitTestVisible="{Binding ElementName=PresetPopup, Path=IsOpen, Mode=OneWay, Converter={StaticResource BoolInverterConverter1}}" />
2. C# Converter Code behind
public class BoolInverterConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is bool)
{
return !((bool)value);
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}