1

type の単一の添付プロパティを持つ添付ビヘイビアがありますStoryBoard。ListView のすべての項目にこのプロパティを設定したいと考えています。XAML は次のようになります。

<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デバッガーで を調べると、IsSealedIsFrozenプロパティの両方が に設定されていることがわかりますtrue

対照的に、を使用する必要がないように にMyBehavior.Animation直接設定すると、 は封印されていない状態で届き、ターゲットを設定して正常に実行できます。しかし、それは私が望むところではありません。ListViewStyleStoryBoard

封印されているのはなぜStoryBoardですか? これを防ぐためにできることはありますか?

更新: null チェックの直後にこれを追加することで問題を解決できます:

if(sb.IsSealed)
   sb = sb.Clone();

しかし、私はまだ何が起こっているのか興味があります。どうやらどこか ( Style? Setter?) がオブジェクトを凍結/封印しているようですSetter.Value

4

2 に答える 2

1

私は WPF の専門家とはほど遠いので、Microsoft がこれを選択した理由の詳細を説明することはできません。しかし、私が理解しているように、主な問題は、リソースとして宣言されたオブジェクトが他の複数のオブジェクトと共有される可能性が高いということです。そのため、それを変更することはできません。

それでもリソースルートに行きたい場合は、リソースを代わりに扱うことができ、のオブジェクトに使用されているオブジェクトを変更できる可能性があります。私が言ったように、私は WPF の専門家ではなく、 と の間の違いについてまだ少し曇っていることを認めますが、このシナリオに対処するという漠然とした記憶があります。:){DynamicResource...}{StaticResource...}DynamicResourceStaticResource

于 2015-07-18T04:49:32.113 に答える