简体   繁体   中英

WPF combobox like popup

I am trying to make a custom popup that will be similar to the combobox one.

I used a Toggle button as the header and a Popup for the content.

<ToggleButton IsChecked="{Binding ElementName=Popup, Path=IsOpen, Mode=TwoWay}">
...
</ToggleButton>

<Popup x:Name="Popup" StaysOpen="False">
...
</Popup>

this works great except one case. When the popup is opened and I click on the ToggleButton again, the popup disappears but then reopens right after.

Looks like when I clicked on the toggle button, Popup detected that the mouse click is outside of the popup so it closes itself and sets ToggleButton.IsChecked = false . Then the click sets IsChecked = true so the popup opens again.

Edit: In such case I would like the popup to close just like the behavior of a Combobox.

Is there a way to solve this problem?

Two ways.

One is to locate the popup on top of the button so the user can't click on the button. I don't like that one, but you can do it easily with Placement and so on.

The other is to bind ToggleButton.IsEnabled to Popup.IsOpen , with a boolean "not" converter, so the button is disabled whenever the popup is open.

You could also do that with a style DataTrigger on the button, like this:

<ToggleButton 
    x:Name="PopupButton"
    Content="Open Popup"
    IsChecked="{Binding ElementName=Popup, Path=IsOpen}">
    <ToggleButton.Style>
        <Style TargetType="ToggleButton" BasedOn="{StaticResource {x:Type ToggleButton}}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsOpen, ElementName=Popup}" Value="True">
                    <Setter Property="IsEnabled" Value="False" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ToggleButton.Style>
</ToggleButton>

<Popup 
    x:Name="Popup" 
    StaysOpen="False"
    PlacementTarget="{Binding ElementName=PopupButton}" 
    Placement="Bottom"
    >
    <Label 
        Padding="20" 
        Background="WhiteSmoke" 
        BorderBrush="Black" 
        BorderThickness="1">Content</Label>
</Popup>

Note that you don't need Mode=TwoWay on the IsChecked binding. That's the default for that property.

If you've got more than one of these, I'd write a Style for HeaderedContentControl with a ControlTemplate that puts the header in the ToggleButton content, the content in the Popup , and does the ToggleButton enabling with a ControlTemplate trigger.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM