.net - 如何将 DataTrigger 绑定(bind)到资源定义样式的 Child 属性?

标签 .net wpf binding styles datatrigger

如何根据子属性的变化设置元素的样式?我会接受不同的方法,但期望的结果只是只要子属性 (IsPressed) 为 true,父属性就会以某种方式设置。

如果我们使用内联样式设计一个命名项,我们可以简单地使用 ElementName 来标识我们的子项,但我们甚至可以不那么具体,使用 Child.IsPressed:

<Border Name="parentBorder" Padding="20">
    <Button Name="childButton" Content="Don't Push Me Bro"/>
    <Border.Style>
        <!--Now how can I do this from a static resource where I don't know the elementname?-->
        <Style TargetType="Border">
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Child.IsPressed}" Value="True">
                     <Setter Property="Background" Value="Blue"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Border.Style>
</Border>

但是,由于我想重用该样式并设置多个边框的样式,因此我想将其移动到相同的资源,当然,我们假设 Child 将始终是一个按钮:

<Style x:Key="ButtonBorder" TargetType="{x:Type Border}">
    <Style.Triggers>                
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Child.IsPressed}" Value="True">
            <Setter Property="Background" Value="Blue"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

最好的方法是什么,或者我错过了什么?我可以看到,当“Child”用作内联样式时,智能感知对 Child 的颜色会有所不同,我确信这意味着什么。从资源定义的样式中假设有关 Child 类型的信息是没有好处的吗?

最佳答案

您可以为此使用附加属性。例如:

public static class Attached
{
    public static readonly DependencyProperty RelatedControlProperty = DependencyProperty.RegisterAttached(
        "RelatedControl", typeof(UIElement), typeof(Attached));

    public static void SetRelatedControl (DependencyObject element, UIElement value)
    {
        element.SetValue(RelatedControlProperty, value);
    }

    public static UIElement GetRelatedControl (DependencyObject element)
    {
        return (UIElement)element.GetValue(RelatedControlProperty);
    }
}

此属性没有逻辑,它只是用于以您喜欢的任何方式“连接”控件。

在样式中,您可以读取控件的附加属性:

<Style x:Key="ButtonBorder" TargetType="{x:Type Border}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding 
                RelativeSource={RelativeSource Self}, 
                Path=(local:Attached.RelatedControl).IsPressed}" Value="True">
            <Setter Property="Background" Value="Blue"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

当您创建控件时,您可以将附加属性设置为子控件:

<Border Name="parentBorder" Padding="20" Style="{StaticResource ButtonBorder}"
        local:Attached.RelatedControl="{x:Reference childButton}">
    <Button Name="childButton" Content="Don't Push Me Bro"/>
</Border>

我不建议使用 Child 属性,因为它会使您的设计变得脆弱。您假设一个控件将恰好包含一个控件,并且仅直接包含。如果您将按钮放在边框内的网格内,它将停止工作。将样式关系与逻辑子关系分离将使样式更加灵活。

如果您真正想要的是仅对直接包含按钮的边框使用边框样式,也许您应该覆盖按钮的模板。

关于.net - 如何将 DataTrigger 绑定(bind)到资源定义样式的 Child 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30384821/

相关文章:

wpf - 为什么将 DependencyProperty 成员声明为 public 不 protected ?

function - 在 scala 中将函数与条件逻辑绑定(bind)

.net - .NET 中的对象图序列化和代码版本升级

c# - .Net StreamWriter.BaseStream,这个定义是什么意思? "Gets the underlying stream that interfaces with a backing store."

.net - 为什么 WPF 支持绑定(bind)到对象的属性,但不支持绑定(bind)字段?

c# - 将 UserControl 转换为自定义控件

.net - 到 PerformanceCounter 还是编写自定义监控?

c# - 在前面使用图像和控件

ruby - Ruby的 "binding"和Scope Chain一样吗?

variables - 在 Haskell 中,为什么将值绑定(bind)到变量名不再强制系统提交类型?