У меня есть прикрепленное поведение, которое имеет одно присоединенное свойство типа StoryBoard
. Я хочу установить это свойство для каждого элемента в ListView. XAML выглядит примерно так:Объект StoryBoard становится доступным только для чтения, если задано стилем
<Grid>
<Grid.Resources>
<Storyboard x:Key="TheAnimation" x:Shared="False">
<DoubleAnimation From="0.0" To="1.0" Duration="0:0:0.20"
Storyboard.TargetProperty="Opacity" />
</Storyboard>
</Grid.Resources>
<ListView>
<ListView.Resources>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="local:MyBehavior.Animation"
Value="{StaticResource TheAnimation}" />
</Style>
</ListView.Resources>
</ListView>
</Grid>
Пока все хорошо. Затем код в «MyBehavior» пытается сделать это:
private static void AnimationChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var listViewItem = d as ListViewItem;
if (d == null)
return;
var sb = e.NewValue as Storyboard;
if (sb == null)
return;
Storyboard.SetTarget(sb, listViewItem);
sb.Begin();
}
Но InvalidOperationException
брошено на призыв к StoryBoard.SetTarget()
: «Невозможно установить свойство на объекте„System.Windows.Media.Animation.Storyboard“потому, что он находится в состоянии только для чтения ». Если я проведу проверку Storyboard
в отладчике, я вижу, что для его свойств IsSealed
и IsFrozen
установлено значение true
.
В противоположность этому, если я изложу MyBehavior.Animation
непосредственно на ListView
, так что мне не нужно использовать Style
, то StoryBoard
прибывает вскрыты, и я могу поставить перед собой цель и запустить его успешно. Но я не хочу этого делать.
Почему мой StoryBoard
запечатан, и есть ли что-нибудь, что я могу сделать, чтобы предотвратить это?
Обновление: Я могу решить мою проблему, добавив это право после нулевой проверки:
if(sb.IsSealed)
sb = sb.Clone();
Но я все еще интересно, что происходит. Видимо что-то где-то (Style
? Setter
?) Замерзает/запечатывает объект в Setter.Value
.
Это имеет смысл, когда вы отступаете и думаете об этом (я думаю). Xaml 'Style' узел предположительно переводится в один объект' Style'. Этот единственный объект вместе с объектами «Value» в его «Setter's» потенциально распределяется между несколькими объектами. Поэтому, если один из них каким-то образом перехватывает объект «Value» («PropertyChangedCalledback» в моем случае) и изменяет его, он будет непреднамеренно влиять на все остальные объекты, которые разделяют стиль. Разработчики инфраструктуры ожидали этого и запечатали «Value's», чтобы убедиться, что этого не произойдет. По крайней мере, это мое предположение. – dlf
Этот процесс мыслей привел меня к этому [связанный вопрос] (http://stackoverflow.com/q/9235428/3549027) – dlf
[Также по теме] (http://www.pcreview.co.uk/threads/wpf- using-storyboards in-custom-control.3591259 /) – dlf