如果在 Element 中设置,WPF 触发器将不会设置属性

Posted

技术标签:

【中文标题】如果在 Element 中设置,WPF 触发器将不会设置属性【英文标题】:WPF Trigger won't set property if set in Element 【发布时间】:2021-06-02 02:30:24 【问题描述】:

这种行为对我来说似乎非常奇怪,我认为我做错了什么来得到它。我有一个ContentControl,它使用 DataTemplete 来呈现 TabControl。我希望在没有打开标签时显示图像,并在有标签时隐藏。但问题来了:

<Image Name="image1" Stretch="Uniform" Visibility="Hidden" Source="/Affinity;component/Images/affinity_logo.png">
            <Image.Style>
                <Style TargetType="Image">
                    <Style.Triggers>
                        <DataTrigger Binding="Binding Items.Count, ElementName=tabcontrolworkspaces"
                        Value="0">
                            <Setter Property="Visibility" Value="Visible" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Image.Style>
        </Image>

这行不通……有点。

我已经在 Visiblity 和 Margin 上对此进行了测试(只是为了确定)。此触发器将更改属性,除非该属性在 Image 标记中定义。如果是,触发器将不会更新该属性。因此,如果我没有为图像定义可见性,并且触发器将其隐藏,它就可以工作。问题是,默认值为 Visible,当 value=0 时触发器需要显示,否则隐藏。

为什么触发器不会覆盖显式定义的属性?这不是它的目的吗?

【问题讨论】:

这能回答你的问题吗? DataTrigger not firing 【参考方案1】:

在样式和触发器中设置您的可见性

我在 DataTriggers 中多次遇到这种奇怪的行为,有时 DataTrigger Setter 不会生效,除非在 Style 中也定义了 Setter。

不起作用

<Image Visibility="Collapsed">
    <Image.Style>
        <Style TargetType="Image">
            <Style.Triggers>
                <DataTrigger Binding="Binding Something" Value="0">
                    <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    <Image.Style>
</Image>

会起作用

<Image>
    <Image.Style>
        <Style TargetType="Image">
            <Setter Property="Visibility" Value="Collapsed" />
            <Style.Triggers>
                <DataTrigger Binding="Binding Something" Value="0">
                    <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    <Image.Style>
</Image>

编辑:请参阅the accepted answer,了解为什么这不起作用。它与确定依赖属性的顺序有关,其中&lt;Tag&gt; 中定义的属性始终优先于触发值。

【讨论】:

【参考方案2】:

当触发器为真时,它会将值更改为所需的值。当它不再为真时,它会将值返回到先前的值。它不会将其更改为不需要的值。

这意味着如果原始值可见,并且您将其更改为可见,则当触发器不再处于活动状态时,该值将恢复为可见。

【讨论】:

【参考方案3】:

这是正常的Dependency Property Value Precedence。在 Image 上设置它的优先级为 #3,而在 Style 触发器中的优先级较低,为 #6。

您可以这样做:

<Image Name="image1" Stretch="Uniform" Source="/Affinity;component/Images/affinity_logo.png">
    <Image.Style>
        <Style TargetType="Image">
            <Setter Property="Visibility" Value="Hidden" />
            <Style.Triggers>
                <DataTrigger Binding="Binding Items.Count, ElementName=tabcontrolworkspaces"
                    Value="0">
                    <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Image.Style>
</Image>

【讨论】:

以上是关于如果在 Element 中设置,WPF 触发器将不会设置属性的主要内容,如果未能解决你的问题,请参考以下文章

WPF:一旦我在代码中设置了一个属性,它就会永远忽略 XAML 绑定......我该如何防止这种情况发生?

如果应用程序已通过深层链接打开,Android 深层链接将不起作用

在代码中设置 WPF 图像源

在 RichTextBox WPF 中设置文化/语言

如何在WPF中设置小扩展头和扩展内容?

在 .net 5 WPF 应用程序中设置文化