覆盖 2 个控件并使用 WPF 切换哪一个可见

Posted

技术标签:

【中文标题】覆盖 2 个控件并使用 WPF 切换哪一个可见【英文标题】:Overlay 2 controls and toggle which one is visible using WPF 【发布时间】:2011-10-05 08:04:09 【问题描述】:

这是一个适用于任何 WPF 控件的一般问题。

我要做的是将两个控件放在一起并切换可见。

即我想控制它们的可见性,以便一次只能看到一个控件。 一个控件通常会被隐藏,但在某些事件时会显示在另一个控件之上。

我曾尝试更改 z 顺序并尝试使用可见性属性,但是虽然我可以使正常隐藏的控件出现,但正常显示的控件也是可见的。

例如下面的按钮通常是隐藏的,但是在单击菜单项时,例如,将设置视图模型中的 ShowAboutBox 属性,从而更改可见性属性。此时按钮应该可见,而不是停靠面板。

<Grid>
    <Button Visibility="Binding ShowAboutBox, Converter=StaticResource BoolToVisConverter">
        <Button.Content>About My App</Button.Content></Button>
    <DockPanel Canvas.ZIndex="0"  LastChildFill="True"></DockPanel>
</Grid>

我在 WPF 方面没有那么丰富的经验,但假设这应该很容易 - 有什么建议吗?

编辑:

上面的代码显示了我尝试过的多种技术。并且可能混淆了这个问题。最近我尝试了以下方法也无济于事。

<Grid>
    <Button Visibility="Binding ShowAboutBox, Converter=StaticResource BoolToVisConverter">
        <Button.Content>About My App</Button.Content></Button>
    <DockPanel></DockPanel>
</Grid>

更改按钮的可见性会使其显示,但停靠面板及其内容仍然在按钮顶部可见。 (由于 z 顺序,按钮显示在停靠面板后面)。

我想我可以同时切换停靠面板的可见性(与按钮相反),但我希望避免这种情况。

【问题讨论】:

【参考方案1】:

您可以使用通用 BooleanConverter here 并相应地声明 True 和 False 值。

【讨论】:

【参考方案2】:

我也会将 DockPanel 的 Visibility 绑定到 ShowAboutBox,但使用的是逆转换器。我为这种类型的场景创建了一堆方便的小转换器:

<Grid>
    <Button Visibility="Binding ShowAboutBox, Converter=StaticResource BoolToVisConverter">About My App</Button>
    <DockPanel Visibility="Binding ShowAboutBox, Converter=StaticResource BoolToInverseVisConverter"></DockPanel>
</Grid>

还有基本的转换器(可以扩展为支持空值等):

public class BooleanToInverseVisibilityConverter : IValueConverter 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
        return (bool) value ? Visibility.Collapsed : Visibility.Visible;
    

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
        return null;
    


【讨论】:

是的,我最后就是这么做的。当你打字时,我得出了这个结论。由于我是 WPF 新手,我有时会担心不使用内置功能会使事情变得过于复杂。认为可能有一种使用更少代码的方法。 我知道你的意思。您可以通过使用触发器单独在 XAML 中以另一种方式完成它,但在我看来,这会给 XAML 文件添加很多不必要的膨胀,并且不能以一种好的方式重用。正如我所说,我现在已经确定了我自己的方便转换器库,我在所有 WPF 项目中都使用了它。我觉得效果很好。【参考方案3】:

您的 ZIndex 技巧不起作用,因为该按钮的 zindex 也为 0(因为它是集合中的第一个)。您需要将按钮的 ZIndex 显式更改为高于 0 的值,以便 DockPanel 显示在其顶部。

也就是说,这里正确的解决方案是在隐藏和可见之间切换按钮的可见性属性,根本不改变 ZIndex。

【讨论】:

以上是关于覆盖 2 个控件并使用 WPF 切换哪一个可见的主要内容,如果未能解决你的问题,请参考以下文章

WPF 更改(覆盖)所有控件中的突出显示和边框颜色

WPF中,如何点击一个被image覆盖住的控件。

WPF:如何使用透明画布和可点击子项制作覆盖控件

c# winform 控件层次问题

裁剪 WPF 控件

如果样式已经设置,如何覆盖 WPF 子控件样式?