基于条件的 wpf 可见性

wpf visibility based on a condition

我想根据特定条件显示 StackPanel。在此示例中,我使用了 BorderThickness 属性:

<ContentControl x:Name="gridDati" VirtualizingPanel.VirtualizationMode="Recycling" VirtualizingPanel.ScrollUnit="Item" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
    <ContentControl.Style>
        <Style TargetType="ContentControl">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=Items}" Value="{x:Null}">
                    <Setter Property="BorderThickness" Value="0" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=Items.Count}" Value="0">
                    <Setter Property="BorderThickness" Value="12" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
</ContentControl>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="pnlLoading" Visibility="Visible">
    <Label Content="">
        <Label.Style>
            <Style>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=BorderThickness, ElementName=gridDati, UpdateSourceTrigger=PropertyChanged}" Value="0">
                        <Setter Property="TextBlock.Text" Value="" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=BorderThickness, ElementName=gridDati, UpdateSourceTrigger=PropertyChanged}" Value="12">
                        <Setter Property="TextBlock.Text" Value="STAND BY" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Label.Style>
    </Label>
</StackPanel>

基本上,在后面的代码中,我在 gridDati 上应用了一个模板,而项目计数器仍为零,边框正确设置为 12。之后它变为零(物品绑定)这个行为就是我想要的。

所以,我也想在相同条件下显示 StackPanel,所以我使用了 DataTrigger,但似乎根本没有触发。我怎样才能“link”这两个条件?所以当我在数据网格中有项目时显示堆栈面板?

这是声明 Label 的正确方法,因此您可以获得所需的结果。

<Label>
    <Label.Style>
        <Style TargetType="Label">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=Items.Count}" Value="0">
                    <Setter Property="Content" Value="STAND BY"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Label.Style>
</Label>

但有几点我需要解释一下,以确保您理解我更改的内容和原因。我将从内到外检查 XAML。

首先,我将 Setter 更改为使用正确的 属性 名称。您使用的是 Label,而您的旧 SetterProperty="TextBlock.Text"TextBlock.Text 不是 Label 的有效 属性 名称(不存在这样的 属性),因此这行不通。你要的属性叫Content.

上升一级到 DataTrigger。我没有绑定到绑定到 ItemsgridDati,而是直接绑定到 Items。您可以用另一种方式来做,但在我看来这很不寻常,并且可能会导致无法预料的错误。

接下来,您会注意到我删除了第一个 DataTrigger。 WPF 依赖属性可以通过多种不同的方式设置,并且有一个 precedence 的顺序,其值将接管其他值。 Label 内容的默认值(最低优先级)是空的。当 DataTrigger 应用 Setter 时,它会覆盖该值(它具有更高的优先级)。当 DataTrigger 条件不再满足 (Items.Count != 0) 时,WPF 停止应用 Setter 并且值 恢复 回到默认值,因为那里不再有任何更高优先级的值覆盖它。因此,您不需要添加第二个 DataTrigger 重置为默认值,我会自动执行此操作。

再往上看,您会看到我将起始 Style 标记更改为 <Style TargetType="Label">。设置 StyleTargetType 是常见的做法。这样做还会为 Style 中的 Setter 提供 IntelliSense 选项,这可能会帮助您发现尝试将 TextBlock.Text 用作 属性 名称时所犯的错误。

最后,我从开头的 Label 标签中删除了 Content=""。直接在 XAML 中的元素上设置 属性 的值具有非常高的优先级,它会覆盖所有 StyleDataTrigger。只要它在那里,你在 Style 中所做的任何事情都不会改变 LabelContent