How do I correctly bind a Popup to a ToggleButton?
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>