在Storyboard中的TemplateBinding | ObjectAnimationUsingKeyFrames无法工作

3
我有以下设置。问题在于,如果我切换到“告警”(Alarm)VisualState,那么AlarmBrush没有被设置。我尝试使用不同的“绑定”(见下文),但是我只得到像“System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=AlarmBrush; DataItem=null; target element is 'DiscreteObjectKeyFrame' (HashCode=39320280); target property is 'Value' (type 'Object')”这样的错误信息。
如果我用资源键替换值,那么一切都好了。但是我想要这个状态是动态的,所以静态资源不是选择。

BaseClass

[TemplateVisualState(GroupName = "FooGroup", Name = "Alarm")]
public abstract class BaseClass : Control
{
    public static readonly DependencyProperty AlarmBrushProperty = DependencyProperty.Register("AlarmBrush", typeof(Brush), typeof(BaseClass), null);
    public Brush AlarmBrush
    {
        get { return (Brush)GetValue(AlarmBrushProperty); }
        set { SetValue(AlarmBrushProperty, value); }
    }
}

派生类

public class DerivedClass : BaseClass
{
    public DerivedClass()
    {
        this.DefaultStyleKey = typeof(DerivedClass);
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        VisualStateManager.GoToState(this, "Alarm", true);
    }
}

XAML样式

<Style TargetType="Basic:DerivedClass">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Basic:DerivedClass">
                <Grid>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="FooGroup">
                            <VisualState x:Name="Alarm">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background)" Storyboard.TargetName="AlarmBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{Binding AlarmBrush, RelativeSource={RelativeSource TemplatedParent}}"/>
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type Basic:DerivedClass}}, Path=AlarmBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Border x:Name="AlarmBorder" BorderBrush="{TemplateBinding BorderBrush}" Padding="{TemplateBinding Padding}"  BorderThickness="{TemplateBinding BorderThickness}">
                        <TextBlock Text="test" Foreground="{TemplateBinding Foreground}" TextWrapping="Wrap" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Border>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="BorderThickness" Value="5"/>
</Style>

xaml

<Foo:DerivedClass BorderBrush="#FFDA1F1F" AlarmBrush="#FF00FF0C"/>
1个回答

2
你可能不喜欢这个答案,但我记得这是WPF中的一个限制。 Value 属性需要被冻结,这意味着你不能使用绑定来动态更改它。同样的情况也适用于 ColorAnimationTo 属性。
由于你实际上并没有在动画颜色(动画一个 Brush 将仅立即更改颜色),你可以随时获取 AlarmBorder 的引用并手动设置其 Background

该死..在VisualState中立即更改AlarmBorder的Background是可行的吗?还是我必须放弃VisualStates,改用属性与触发器的简单组合? - Dominic Jonas
@DominicJonas 别使用可视状态,使用带触发器的属性即可。 - Justin XL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接