Элементы управления WPF: как ссылаться на ресурсы в анимации? - PullRequest
2 голосов
/ 02 декабря 2010

Я написал элемент управления и успешно создал раскадровку, чтобы вызывать анимацию во время запускаемых событий.Это изменяет заполнение эллипса в течение некоторого времени.Вместо того, чтобы писать новый RadialGradientBrush каждый раз, когда мне нужно изменить заливку, я предоставил два из них в ресурсах.

РЕДАКТИРОВАТЬ : у меня есть Ellipse, который является основнымКомпонент управления и является то, что влияет на анимацию.Его реализация проста и выглядит следующим образом:

<Ellipse Name="myEllipse" Style="{StaticResource DimStyle}" />

Когда я добавляю его в раскадровку (вместо ссылки на кисть в качестве ресурса), моя анимация работает так, как задумано.Когда я ссылаюсь на кисть как на ресурс, я получаю следующее исключение:

"Cannot find resource named 'IlluminatedStyle'. Resource names are case sensitive."

Внутри раскадровки это место, на которое в данный момент ссылаются:

<UserControl.Resources>
    <Storyboard x:Key="Foo">
        <ObjectAnimationUsingKeyFrames>
            <ObjectAnimationUsingKeyFrames.KeyFrames>
                <DiscreteObjectKeyFrame KeyTime="0:0:0.01" Value="{StaticResource IlluminatedStyle}" />
                <DiscreteObjectKeyFrame KeyTime="0:0:0.85" Value="{StaticResource DimStyle}" />
            </ObjectAnimationUsingKeyFrames.KeyFrames>
        </ObjectAnimationUsingKeyFrames>
     </Storyboard>
</UserControl.Resources>

Стили полностью идентичны, и отличаются только свойства цвета GradientStop, поэтому для примера я приведу только один стиль.

Ссылка на стиль

<UserControl.Resources>
    <Style x:Key="IlluminatedStyle" TargetType="Ellipse">
        <Setter Property="Fill">
            <Setter.Value>
                <RadialGradientBrush>
                    <GradientStop Color="#FF215416" Offset="1"/>
                    <GradientStop Color="#FE38DA2E" Offset="0"/>
                    <GradientStop Color="#FE81FF79" Offset="0.688"/>
                </RadialGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

Так как мне правильно сослаться на такой стиль в моем Storyboard?

Примечание : Storyboard и Style оба содержатся в одном и том же теге UserControl.Resources, но для этого примера разбиты.

EDIT
Я поставил Style перед Storyboard в UserControl.Resources, и теперь я получаю исключение:

  "This Freezable cannot be frozen.
   at System.Windows.Freezable.Freeze()
   at System.Windows.Freezable.GetCurrentValueAsFrozen()
   at System.Windows.Media.Animation.TimelineCollection.GetCurrentValueAsFrozenCore(Freezable source)
   at System.Windows.Freezable.CloneCoreCommon(Freezable sourceFreezable, Boolean useCurrentValue, Boolean cloneFrozenValues)
   at System.Windows.Media.Animation.Timeline.GetCurrentValueAsFrozenCore(Freezable sourceFreezable)
   at System.Windows.Freezable.GetCurrentValueAsFrozen()
   at System.Windows.Media.Animation.Clock..ctor(Timeline timeline)
   at System.Windows.Media.Animation.TimelineGroup.AllocateClock()
   at System.Windows.Media.Animation.Clock.AllocateClock(Timeline timeline, Boolean hasControllableRoot)"

Ответы [ 2 ]

3 голосов
/ 02 декабря 2010

Существует три причины, по которым Freezable не может быть заморожен:

  • Имеет свойства анимации или привязки к данным.
  • У него есть свойства, которые задаются динамическим ресурсом.
  • Содержит замораживаемые подобъекты, которые не могут быть заморожены.

Итак, сначала выясните, какая Freezable вызывает проблемы, а затем проверьте вышеуказанное.

1 голос
/ 02 декабря 2010

Видя, что я новичок в WPF и XAML, я сделал ошибку, сделав свои ресурсы стилем, и не понял, что мог бы просто сделать кисти ресурсом и вообще избегать стилей.

Я сохранилссылка на значения DiscreteObjectKeyFrame s как статические для новых ресурсов кисти.Я изменил Ellipse на это:

<Ellipse Name="myEllipse" Fill="{StaticResource DimBrush" />

Свойство style было удалено, и я непосредственно назначил кисть свойству fill.В теге ObjectAnimationUsingKeyFrames я добавил Fill как Storyboard.TargetProperty, так как я больше не использовал стиль, чтобы наряжать заливку.DiscreteObjectKeyFrame s теперь выглядят так:

<DiscreteObjectKeyFrame KeyTime="0:0:0.01" Value="{StaticResource IlluminatedBrush}" />
<DiscreteObjectKeyFrame KeyTime="0:0:0.85" Value="{StaticResource DimBrush}" />

Мои ресурсы намного проще, без использования стиля и IMO, более элегантно.Также кисти определены до анимации в моем окончательном решении.

<UserControl.Resources>
    <RadialGradientBrush x:Key="DimBrush" >
        <GradientStop Color="#FF21471A" Offset="1"/>
        <GradientStop Color="#FF33802F" Offset="0"/>
        <GradientStop Color="#FF35932F" Offset="0.688"/>
    </RadialGradientBrush>
    <RadialGradientBrush x:Key="IlluminatedBrush">
        <GradientStop Color="#FF215416" Offset="1"/>
        <GradientStop Color="#FE38DA2E" Offset="0"/>
        <GradientStop Color="#FE81FF79" Offset="0.688"/>
    </RadialGradientBrush>
    <!-- Storyboard code follows... -->
</UserControl.Resources>

Теперь все работает так, как задумано.Лучшее предположение, которое я могу сделать, - это то, что стили не замораживаются, поскольку они были компонентами, которые я удалил, и я больше не получаю исключений относительно замораживаемых элементов, которые не могут быть заморожены.

...