【问题标题】:wpf visibility based on a condition基于条件的 wpf 可见性
【发布时间】:2021-05-07 17:15:23
【问题描述】:

我想根据特定条件显示 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,但似乎根本没有触发。我怎样才能“链接”这两个条件?那么当我在数据网格中有项目时显示一个堆栈面板?

【问题讨论】:

    标签: wpf datatrigger stackpanel


    【解决方案1】:

    这是声明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 标记更改为 &lt;Style TargetType="Label"&gt;。通常的做法是设置StyleTargetType。这样做还会为您在 Style 中为 Setters 提供 IntelliSense 选项,这可能有助于您发现尝试使用 TextBlock.Text 作为属性名称时所犯的错误。

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

    【讨论】:

      猜你喜欢
      • 2014-08-26
      • 1970-01-01
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-23
      • 2011-03-30
      • 1970-01-01
      相关资源
      最近更新 更多