基于条件的 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
,而您的旧 Setter
有 Property="TextBlock.Text"
。 TextBlock.Text
不是 Label
的有效 属性 名称(不存在这样的 属性),因此这行不通。你要的属性叫Content
.
上升一级到 DataTrigger
。我没有绑定到绑定到 Items
的 gridDati
,而是直接绑定到 Items
。您可以用另一种方式来做,但在我看来这很不寻常,并且可能会导致无法预料的错误。
接下来,您会注意到我删除了第一个 DataTrigger
。 WPF 依赖属性可以通过多种不同的方式设置,并且有一个 precedence 的顺序,其值将接管其他值。 Label
内容的默认值(最低优先级)是空的。当 DataTrigger
应用 Setter
时,它会覆盖该值(它具有更高的优先级)。当 DataTrigger
条件不再满足 (Items.Count != 0
) 时,WPF 停止应用 Setter
并且值 恢复 回到默认值,因为那里不再有任何更高优先级的值覆盖它。因此,您不需要添加第二个 DataTrigger
重置为默认值,我会自动执行此操作。
再往上看,您会看到我将起始 Style
标记更改为 <Style TargetType="Label">
。设置 Style
的 TargetType
是常见的做法。这样做还会为 Style
中的 Setter
提供 IntelliSense 选项,这可能会帮助您发现尝试将 TextBlock.Text
用作 属性 名称时所犯的错误。
最后,我从开头的 Label
标签中删除了 Content=""
。直接在 XAML 中的元素上设置 属性 的值具有非常高的优先级,它会覆盖所有 Style
和 DataTrigger
。只要它在那里,你在 Style
中所做的任何事情都不会改变 Label
的 Content
。
我想根据特定条件显示 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
,而您的旧 Setter
有 Property="TextBlock.Text"
。 TextBlock.Text
不是 Label
的有效 属性 名称(不存在这样的 属性),因此这行不通。你要的属性叫Content
.
上升一级到 DataTrigger
。我没有绑定到绑定到 Items
的 gridDati
,而是直接绑定到 Items
。您可以用另一种方式来做,但在我看来这很不寻常,并且可能会导致无法预料的错误。
接下来,您会注意到我删除了第一个 DataTrigger
。 WPF 依赖属性可以通过多种不同的方式设置,并且有一个 precedence 的顺序,其值将接管其他值。 Label
内容的默认值(最低优先级)是空的。当 DataTrigger
应用 Setter
时,它会覆盖该值(它具有更高的优先级)。当 DataTrigger
条件不再满足 (Items.Count != 0
) 时,WPF 停止应用 Setter
并且值 恢复 回到默认值,因为那里不再有任何更高优先级的值覆盖它。因此,您不需要添加第二个 DataTrigger
重置为默认值,我会自动执行此操作。
再往上看,您会看到我将起始 Style
标记更改为 <Style TargetType="Label">
。设置 Style
的 TargetType
是常见的做法。这样做还会为 Style
中的 Setter
提供 IntelliSense 选项,这可能会帮助您发现尝试将 TextBlock.Text
用作 属性 名称时所犯的错误。
最后,我从开头的 Label
标签中删除了 Content=""
。直接在 XAML 中的元素上设置 属性 的值具有非常高的优先级,它会覆盖所有 Style
和 DataTrigger
。只要它在那里,你在 Style
中所做的任何事情都不会改变 Label
的 Content
。