如何从资源定义的样式将DataTrigger绑定到Child属性?

时间:2015-05-21 21:38:35

标签: .net wpf binding styles datatrigger

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

如果我们使用内联样式设置一个命名项目的样式,我们可以使用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>

但是因为我想重复使用几个Borders的样式和样式,我想将它移动到一个资源,这是相同的,除了我们当然假设Child永远是一个Button:

<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>

最好的方法是什么,或者我错过了什么?我可以看到&#34; Child&#34;用作内联样式,智能感知颜色与儿童不同,我确信这意味着什么。从资源定义的样式中假设关于Child类型的事情是不是很好吗?

1 个答案:

答案 0 :(得分:2)

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

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);
    }
}

此属性没有逻辑,它仅用于&#34;连接&#34;控制你喜欢的任何方式。

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

<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属性,因为它会使您的设计变得脆弱。您假设一个控件只包含一个控件而且只能直接控制。如果在边框内的网格中放置一个按钮,它将停止工作。从逻辑子关系中分离样式关系将使样式更加灵活。

如果您真正想要的是仅将边框样式用于直接包含按钮的边框,则可能只需覆盖按钮的模板。