为什么WPF弹出窗口在单击其背景区域时会关闭?

时间:2009-03-06 17:56:58

标签: .net wpf popup focus

我有一个WPF Popup控件,其中包含一些用很多空格布局的编辑控件(列表框,文本框,复选框)。

Popup.StaysOpen设置为False,这是必需的。如果用户单击应用程序中的其他位置,则应认为编辑操作已中止,弹出窗口应关闭。

不幸的是,只要用户在弹出窗口的背景区域(编辑控件之间的空格)中单击,弹出窗口也会关闭。

我尝试将弹出窗口设置为Focusable。我也试过设置弹出窗口的孩子(Border)是可聚焦的。两个方面都没有运气。

此外,鼠标事件似乎通过弹出窗口。当我点击它时,弹出窗口下面的任何元素变得集中。尽管PopupBorder(我正在点击)同时将IsHitTestVisibleFocusable都设置为true

5 个答案:

答案 0 :(得分:33)

最后,我发现以下情况有效。鉴于...

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

...我在调用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;

答案 1 :(得分:7)

在Popup和Border上忽略Focusable似乎很奇怪。当鼠标悬停在边框上时,我可以通过在触发器中更改StaysOpen来解决您的问题:

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <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>

答案 2 :(得分:1)

我最好的猜测是你有一些透明度问题。尝试在弹出窗口中设置背景画笔。

答案 3 :(得分:1)

你不是把你的Popup嵌套在ToggleButton或其他类型的Button中吗?然后在Popup级别停止路由事件将是合乎逻辑的工作。

答案 4 :(得分:0)

你可以设置 StayOpen = true,并在Popup的MouseLeave事件timer.Start()中设置一个计时器,例如3秒后,在MouseEnter事件中关闭此弹出窗口,计时器。停止()。 它会起作用。