我一直在努力解决这个问题很长一段时间,我似乎无法找到合适的解决方案。这是被剥离的场景。想象一下,你有以下XAML:
<Grid x:Name="LayoutRoot" Background="White">
<Grid x:Name="Host" Width="200" Height="200">
<Popup IsOpen="True">
<Button Content="Some Button" Click="Button_Click" />
</Popup>
</Grid>
</Grid>
在 Button_Click 事件处理程序中,我所做的就是折叠名称为主机的网格。
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Host.Visibility = System.Windows.Visibility.Collapsed;
}
我的预期是Popup会因为隐藏按钮而关闭。我知道Popups不在同一个VisualTree中,我理解为什么这可能不像我期望的那样工作,但应该有某种机制让它自动发生。我想到的唯一解决方法是在LayoutUpdated上遍历可视化树,并询问每个Button的父级是否可见,如果我遇到折叠的父级 - >关闭Popup。但是,想象一下拥有巨大可视树的性能。在每个布局过程中遍历可视树是疯狂的。 我愿意接受任何建议。
编辑:似乎我没有完全解释我的情景。如果其父级的 ANY 被折叠(而不仅仅是直接的),则会崩溃弹出窗口。在WPF中,有一个名为 IsVisible 的有用属性,它与Visibility不同。例如,可见性可能仍然是可见,但在此方案中 IsVisible 将 false 。
最诚挚的问候, ķ
答案 0 :(得分:0)
我认为你在弹出控件中发现了一个错误,或者至少是一个“怪异” - 请检查一下:
我最初的想法是简单地将弹出窗口的可见性绑定到主机上。这应该工作。
<Grid x:Name="LayoutRoot" Background="White">
<Grid x:Name="Host" Width="200" Height="200" Background="Aqua">
<Popup IsOpen="True" Visibility="{Binding ElementName=Host, Path=Visibility}" Height="100" Width="100">
<Button Content="Some Button" Click="Button_Click"/>
</Popup>
</Grid>
</Grid>
但它不起作用。 “主机”网格消失,但我仍然看到按钮。这让我很困惑,所以我解雇了Silverlight间谍,并检查了这一点 - 设置弹出窗口的可见性不会隐藏按钮!
无论如何,为了使这项工作,你只需要按一下东西,以便将Host Visibility与IsOpen属性联系起来。我在这里使用了转换器:
<UserControl.Resources>
<Junk:VisibilityToBoolConverter x:Key="VisibilityToBoolConverter"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Grid x:Name="Host" Width="200" Height="200" Background="Aqua">
<Popup IsOpen="{Binding ElementName=Host, Path=Visibility, Converter={StaticResource VisibilityToBoolConverter}}" Height="100" Width="100">
<Button Content="Some Button" Click="Button_Click"/>
</Popup>
</Grid>
</Grid>
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Host.Visibility = System.Windows.Visibility.Collapsed;
}
public class VisibilityToBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((Visibility) value) == Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
这对我有用。
答案 1 :(得分:-1)
如果您只想关闭弹出窗口,为什么不将弹出窗口中的IsOpen设置为false。
<Grid x:Name="LayoutRoot" Background="White">
<Grid x:Name="Host" Width="200" Height="200">
<Popup x:Name="HostPopup" IsOpen="True">
<Button Content="Some Button" Click="Button_Click" />
</Popup>
</Grid>
</Grid>
private void Button_Click(object sender, RoutedEventArgs e)
{
this.HostPopup.IsOpen = false;
}
这会关闭弹出窗口。