views:

3500

answers:

4

I have a WPF Popup control that contains some editing controls (list boxes, text boxes, check boxes) laid out with quite a bit of whitespace.

Popup.StaysOpen is set to False, which is required. If the user clicks elsewhere in the application, the editing operation should be considered aborted and the popup should close.

Unfortunately the popup also closes whenever the user clicks within the background region of the popup (the space between the edit controls).

I've tried setting the popup to be Focusable. I've also tried setting the popup's child (a Border) to be focusable. No luck on either front.

Furthermore, the mouse event seems to tunnel through the popup. Whatever element is underneath the popup when I click it becomes focused. This is despite both the Popup and the Border (into which I'm clicking) having both IsHitTestVisible and Focusable set to true.

A: 

My best guess is you have some transparency issues going on. Try setting a background brush on the popup.

Bryan Anderson
Thanks for your answer. The border control fills the entire region of the popup and has a solid brush set
Drew Noakes
+5  A: 

In the end, I found that the following worked. Given...

<Popup x:Name="_popup"
       StaysOpen="False"
       PopupAnimation="Slide"
       AllowsTransparency="True">

...I used this code in the constructor after calling InitializeComponent...

// Ensure that any mouse event that gets through to the
// popup is considered handled, otherwise the popup would close
_popup.MouseDown += (s, e) => e.Handled = true;
Drew Noakes
+2  A: 

It does seem odd that it would ignore Focusable on the Popup and Border. I was able to fix your problem by changing StaysOpen in a trigger when the mouse is over the Border:

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <ToggleButton x:Name="btnPop" Content="Pop!" Width="100" Height="50"/>
    <Popup Placement="Bottom" PlacementTarget="{Binding ElementName=btnPop}" IsOpen="{Binding IsChecked, ElementName=btnPop}">
        <Popup.Style>
            <Style TargetType="{x:Type Popup}">
                <Setter Property="StaysOpen" Value="False"/>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsMouseOver, ElementName=brd}" Value="True">
                        <Setter Property="StaysOpen" Value="True"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Popup.Style>
        <Border x:Name="brd" Background="White" BorderThickness="1" BorderBrush="Black">
            <StackPanel>
                <TextBox Margin="10"/>
                <TextBlock Text="Some text is here." Margin="10"/>
                <TextBox Margin="10"/>
            </StackPanel>            
        </Border>
    </Popup>
</Grid>
Robert Macnee
A: 

Don't you have your Popup nested in a ToggleButton or other kind of Button? Then stopping the routed event at Popup level would be logical to get working.

PaN1C_Showt1Me