基于IsFocused与IsVisible控制Popup异常:错误提示未随窗口隐藏
解决Popup错误提示框在窗口隐藏后仍显示的问题
我明白你遇到的困扰了——当关闭对话框(隐藏窗口)时,原本绑定到TextBox焦点的错误提示Popup没有自动关闭,即使你加了检测errorBorder可见性的触发器也没用。这其实是绑定优先级和触发器条件选择不当导致的问题,我来给你一步步解决:
问题根源分析
- 绑定优先级冲突:你直接给Popup的
IsOpen设置了OneWay绑定到AdornedElement.IsFocused,而Style中的DataTrigger的Setter优先级低于直接的属性绑定,所以即使触发器条件满足,也无法覆盖原有的绑定值。 - 错误的触发条件:
errorBorder的IsVisible在窗口隐藏时并不会自动变为False,因为Validation.ErrorTemplate的元素位于Adorner层,窗口的Visibility变化不会直接影响到它。
修正方案
我们需要用MultiDataTrigger来组合多个生效条件,确保Popup只有在以下所有条件满足时才保持打开:
- TextBox获得焦点(
AdornedElement.IsFocused == True) - TextBox所在的窗口处于可见状态(
AdornedElement.IsVisible == True) - TextBox存在验证错误(
Validation.HasError == True)
同时,要移除Popup上直接的IsOpen绑定,把所有控制逻辑放到Style中,这样触发器才能正常生效。
修正后的完整XAML代码
<ControlTemplate x:Key="errorToolTipTemplate"> <Grid> <Border BorderBrush="#EF5B7C" BorderThickness="1" Background="#EF5B7C" Opacity="0.4" IsHitTestVisible="False" x:Name="errorBorder" /> <AdornedElementPlaceholder x:Name="placeholder" /> <Popup x:Name="popup" AllowsTransparency="True" PopupAnimation="Fade" Placement="Right" VerticalOffset="-3" PlacementTarget="{Binding ElementName=errorBorder}"> <Popup.Style> <Style TargetType="{x:Type Popup}"> <Setter Property="IsOpen" Value="False"/> <Style.Triggers> <MultiDataTrigger> <MultiDataTrigger.Conditions> <!-- 条件1:TextBox获得焦点 --> <Condition Binding="{Binding ElementName=placeholder, Path=AdornedElement.IsFocused}" Value="True"/> <!-- 条件2:TextBox所在窗口可见 --> <Condition Binding="{Binding ElementName=placeholder, Path=AdornedElement.IsVisible}" Value="True"/> <!-- 条件3:TextBox存在验证错误 --> <Condition Binding="{Binding ElementName=placeholder, Path=AdornedElement.(Validation.HasError)}" Value="True"/> </MultiDataTrigger.Conditions> <Setter Property="IsOpen" Value="True"/> </MultiDataTrigger> <!-- 额外保险:当验证错误消失时关闭Popup --> <DataTrigger Binding="{Binding ElementName=placeholder, Path=AdornedElement.(Validation.HasError)}" Value="False"> <Setter Property="IsOpen" Value="False"/> </DataTrigger> </Style.Triggers> </Style> </Popup.Style> <DockPanel> <Polygon VerticalAlignment="Center" Points="0,5 5,0 5,10" Fill="#EF5B7C" Stretch="Fill" /> <Border Background="White" BorderBrush="#EF5B7C" BorderThickness="1" CornerRadius="4" Padding="2"> <DockPanel> <Image Height="20" Width="20" VerticalAlignment="Center" Source="Images/C04_32.png" /> <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="{StaticResource errorBrush}" FontWeight="Bold" Margin="2,0,0,0" Text="{Binding ElementName=placeholder, Path=AdornedElement.ToolTip, Mode=OneWay}" /> </DockPanel> </Border> </DockPanel> </Popup> </Grid> </ControlTemplate> <!--Textbox style--> <Style TargetType="{x:Type TextBox}"> <Setter Property="Validation.ErrorTemplate" Value="{DynamicResource errorToolTipTemplate}" /> </Style>
关键修改点说明
- 移除了Popup上直接的
IsOpen绑定,改为在Style中默认设置IsOpen=False - 添加
MultiDataTrigger组合三个核心条件,确保只有在TextBox聚焦、窗口可见且有错误时才打开Popup - 增加了单独的DataTrigger,当验证错误消失时强制关闭Popup,提升鲁棒性
这样修改后,当你关闭对话框(窗口变为隐藏)时,AdornedElement.IsVisible会变为False,MultiDataTrigger的条件不再满足,Popup就会自动关闭了。
内容的提问来源于stack exchange,提问作者IBRA
相关产品推荐
相关产品推荐

