TemplateBinding в раскадровке | ObjectAnimationUsingKeyFrames не работает
У меня есть следующие настройки. проблема в том, что если я переключусь на 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')
,
Если я заменю значение ResourceKey, то все в порядке. Но я хочу, чтобы это состояние было динамичным, поэтому статический ресурс - это не вариант.
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); }
}
}
DerivedClass
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 ответ
Вы будете ненавидеть это, но я помню, что это одно из ограничений в WPF. Value
свойство должно быть заморожено, что означает, что вы не можете использовать привязки для его динамического изменения. То же самое относится и к To
свойство ColorAnimation
,
Так как вы на самом деле не анимация цвета (анимация Brush
будет просто изменить цвет мгновенно), вы всегда можете получить ссылку на AlarmBorder
и вручную установить его Background
,