如何将 DataTrigger 从 resource-defined 样式绑定到 Child 属性?
How would you bind a DataTrigger to a Child property from a resource-defined Style?
如何根据 child 属性的变化设置元素样式?我会接受不同的方法,但期望的结果只是 parent 属性 以某种方式设置,只要 child 属性 (IsPressed) 为真。
如果我们用 in-line 样式设置一个命名项目的样式,我们可以使用 ElementName 简单地标识我们的 child,但我们甚至可以不那么具体并使用 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 不同,我确信这意味着什么。从 resource-defined 样式假设 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);
}
}
这个属性没有逻辑,它只是用于"connecting"控制你喜欢的任何方式。
在样式中,您阅读了您控件的附件属性:
<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
属性,因为它会使您的设计变得脆弱。您假设一个控件将只包含一个控件并且仅直接包含。如果将按钮放在边框内的网格内,它将停止工作。从逻辑子关系中分离样式关系将使样式更加灵活。
如果您真正想要的是仅对直接包含按钮的边框使用边框样式,也许您应该只覆盖按钮的模板。
如何根据 child 属性的变化设置元素样式?我会接受不同的方法,但期望的结果只是 parent 属性 以某种方式设置,只要 child 属性 (IsPressed) 为真。
如果我们用 in-line 样式设置一个命名项目的样式,我们可以使用 ElementName 简单地标识我们的 child,但我们甚至可以不那么具体并使用 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 不同,我确信这意味着什么。从 resource-defined 样式假设 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);
}
}
这个属性没有逻辑,它只是用于"connecting"控制你喜欢的任何方式。
在样式中,您阅读了您控件的附件属性:
<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
属性,因为它会使您的设计变得脆弱。您假设一个控件将只包含一个控件并且仅直接包含。如果将按钮放在边框内的网格内,它将停止工作。从逻辑子关系中分离样式关系将使样式更加灵活。
如果您真正想要的是仅对直接包含按钮的边框使用边框样式,也许您应该只覆盖按钮的模板。