Wednesday, April 2, 2014

ToggleButton with Popup

Need a ToogleButton with a Popup that behaves nicely?

Have you done this (see XAML below) and wondered why the popup closes and reopens when you click the ToggleButton again and again, the ToggleButton is always checked until you click outside the button or the popup.

<Grid>
    <ToggleButton Name="tbWithPopup" Width="30" Height="30"
               IsChecked="{Binding ElementName=pUp, Path=IsOpen}">
        <Polygon Points="0,0 2,0, 1,1" Fill="Black" Stretch="Fill" />
    </ToggleButton>
        
    <Popup Name="pUp"
           PlacementTarget="{Binding ElementName=tbWithPopup}"
           AllowsTransparency="True" StaysOpen="False" Width="200">
        <RichTextBox IsReadOnly="True">
            <RichTextBox.Document>
                <FlowDocument>
                    <Paragraph>
                       Checkout WPF Tat for more elegant 
                       solutions
                    </Paragraph>
                </FlowDocument>
            </RichTextBox.Document>
        </RichTextBox>
    </Popup>
</Grid>

What is happening, is that when you click the ToggleButton the second time, the Popup closes, resets the ToggleButton's IsChecked state to False and your click causes the ToggleButton's IsChecked state to change to True again, and thus the Popup closes and reopens.

How do we solve this? 

Turns out there is a very elegant solution to this problem. By setting the IsHitTestVisble property of the ToggleButton to False when the Popup is open. 

We can easy do this in XAML by adding a style to the ToggleButton. Like this ...

<ToggleButton.Style>
    <Style TargetType="ToggleButton">
        <Style.Triggers>
            <DataTrigger Binding="{Binding ElementName=pUp, Path=IsOpen}" 
                         Value="True">
                <Setter Property="IsHitTestVisible" Value="False" />
            </DataTrigger>
         </Style.Triggers>
    </Style>
</ToggleButton.Style>

Now, everything behaves as you would expect, and no code behind required :)

2 comments:

  1. Thank you wise guru. I tried many "solutions" posted by others, none of which worked properly.

    ReplyDelete
  2. Thank you so much. After spending a day on searching, I found this ultimate solution

    ReplyDelete