I am trying to do something that seems relatively simple and logic from a user interface level but I have one bug that is very annoying. I have a ToggleButton a
Stephans answers has the disadvantage, that the desired behaviour of closing the popup whenever it loses focus also disappears.
I solved it by disabling the toggle-button when the popup is open. An alternative would be to use the IsHitTestVisible Property instead of is enabled:
<ToggleButton x:Name="TogglePopupButton" Content="My Popup Toggle Button" Width="100" IsEnabled="{Binding ElementName=ToggledPopup, Path=IsOpen, Converter={StaticResource BoolToInvertedBoolConverter}}"/>
<Popup x:Name="ToggledPopup" StaysOpen="False" IsOpen="{Binding IsChecked, ElementName=TogglePopupButton, Mode=TwoWay}">
<Border Width="100" Height="200" Background="White" BorderThickness="1" BorderBrush="Black">
<TextBlock>This is a test</TextBlock>
</Border>
</Popup>
The converter looks like this:
public class BoolToInvertedBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is bool)
{
bool boolValue = (bool)value;
return !boolValue;
}
else
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException("ConvertBack() of BoolToInvertedBoolConverter is not implemented");
}
}
Solution without IValueConverter:
<Grid>
<ToggleButton x:Name="TogglePopupButton" Content="My Popup Toggle Button" Width="100" >
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="IsHitTestVisible" Value="True"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=Popup, Path=IsOpen}" Value="True">
<Setter Property="IsHitTestVisible" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
<Popup StaysOpen="false" IsOpen="{Binding IsChecked, ElementName=TogglePopupButton, Mode=TwoWay}"
PlacementTarget="{Binding ElementName=TogglePopupButton}" PopupAnimation="Slide"
x:Name="Popup">
<Border Width="100" Height="200" Background="White" BorderThickness="1" BorderBrush="Black">
<TextBlock>This is a test</TextBlock>
</Border>
</Popup>
</Grid>
On the ToggleButton set the Property ClickMode="Press"apixeltoofar
Set StaysOpen="True" for your Popup
From MSDN:
Gets or sets a value that indicates whether the Popup control closes when the control is no longer in focus.
[...]
trueif thePopupcontrol closes whenIsOpenproperty is set tofalse;
falseif thePopupcontrol closes when a mouse or keyboard event occurs outside thePopupcontrol.