2012-03-29 24 views
4

問題は、私がストーリーボードを含む2番目のスタイルにスタイルを設定すると、Trigger.ExitActionに例外があることです。スタイルの名前スコープにストーリーボードが見つかりません

  • 下のデモのいずれかの矩形の上にマウスを置くと、ストーリーボードが実行され、長方形が色を変えます。
  • マウスがstyle = 'rectStyle'の赤い矩形を離れると、ストーリーボードは削除されます。
  • マウスが(派生スタイルを使用しています)青い四角形を離れたとき、私はこの例外を取得:

    と、InvalidOperationException: 「MouseOverStoryboard」名前「はSystem.Windows.Style」という名前のスコープで見つけることができません。だから、

  • は、それが基本スタイルでストーリーボードを持って有効ですか?
  • このエラーが発生しないようにBeginStoryboardNameをより明示的に参照する方法はありますか?
  • 他の提案はありますか?

最後に、私が達成しようとしているのはトリガーとストーリーボードを含むスタイルをいくつかの他のスタイルで再利用することです。

はここで、問題を示し、いくつかの簡単なコードです:あなたはStopStoryboardを含める場合

<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition/> 
     <RowDefinition/> 
    </Grid.RowDefinitions> 

    <Grid.Resources> 
     <Style x:Key="rectStyle" TargetType="{x:Type Rectangle}"> 
      <Style.Triggers> 
       <Trigger Property="IsMouseOver" Value="True"> 
        <Trigger.EnterActions> 
         <BeginStoryboard x:Name="MouseOverStoryboard"> 
          <Storyboard> 
           <ColorAnimation To="PaleGoldenrod" 
            Storyboard.TargetProperty="(Fill).(Color)" 
            Duration="0:0:1"/> 
          </Storyboard> 
         </BeginStoryboard> 
        </Trigger.EnterActions> 
        <Trigger.ExitActions> 
         <StopStoryboard BeginStoryboardName="MouseOverStoryboard"/> 
        </Trigger.ExitActions> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 

     <Style x:Key="rectStyle2" TargetType="{x:Type Rectangle}" 
       BasedOn="{StaticResource rectStyle}"/> 
    </Grid.Resources> 

    <Rectangle Grid.Row="0" Width="100" Height="100" Fill="Red" 
       Style="{StaticResource rectStyle}" /> 
    <Rectangle Grid.Row="1" Width="100" Height="100" Fill="Blue" 
       Style="{StaticResource rectStyle2}" /> 
</Grid> 

答えて

4

あなたの最善の策は、派生スタイルの明確な舵取りすることです。実際には2つのスタイルのインスタンスがあり、スコープは派生スタイルに対して間違っています。私はこれが設計によるものだと信じています。ストーリーボードをリソース内の外側のスコープに抽象化し、ストーリーボードをStaticResourceで参照して、両方のスタイルでトリガーを複製することができます。派生したスタイルの特定の要件があるかもしれないので、あなたの問題を解決できないかもしれませんが、残念なことに選択肢がないと思います。

あなたはこのような何かする必要があると思いますStopStoryboard使用したい場合は、あなたがすべてで基本スタイルを継承することはできませんので:

<Grid> 
<Grid.RowDefinitions> 
    <RowDefinition/> 
    <RowDefinition/> 
</Grid.RowDefinitions> 
<Grid.Resources> 
    <Storyboard x:Key="mouseOver"> 
    <ColorAnimation 
     AutoReverse="True" 
     Duration="0:0:1" 
     RepeatBehavior="Forever" 
     Storyboard.TargetProperty="(Fill).(Color)" 
     To="PaleGoldenrod"/> 
    </Storyboard> 
    <Style x:Key="rectStyle" TargetType="{x:Type Rectangle}"> 
    <Style.Triggers> 
     <Trigger Property="IsMouseOver" Value="True"> 
     <Trigger.EnterActions> 
      <BeginStoryboard x:Name="MouseOverStoryboard" Storyboard="{StaticResource mouseOver}"/> 
     </Trigger.EnterActions> 
     <Trigger.ExitActions> 
      <StopStoryboard BeginStoryboardName="MouseOverStoryboard"/> 
     </Trigger.ExitActions> 
     </Trigger> 
    </Style.Triggers> 
    </Style> 
    <Style x:Key="rectStyle2" TargetType="{x:Type Rectangle}"> 
    <Style.Triggers> 
     <Trigger Property="IsMouseOver" Value="True"> 
     <Trigger.EnterActions> 
      <BeginStoryboard x:Name="MouseOverStoryboard1" Storyboard="{StaticResource mouseOver}"/> 
     </Trigger.EnterActions> 
     <Trigger.ExitActions> 
      <StopStoryboard BeginStoryboardName="MouseOverStoryboard1"/> 
     </Trigger.ExitActions> 
     </Trigger> 
    </Style.Triggers> 
    </Style> 
</Grid.Resources> 
<Rectangle 
    Width="100" 
    Height="100" 
    Grid.Row="0" 
    Fill="Red" 
    Style="{StaticResource rectStyle}"/> 
<Rectangle 
    Width="100" 
    Height="100" 
    Grid.Row="1" 
    Fill="Blue" 
    Style="{StaticResource rectStyle2}"/> 

+0

[OK]を感謝をむしばみます。MSの情報は似ていました "WPFでは、現在の実装に基づいて、これは期待される動作です。各Styleクラスは独自のインスタンスを作成するため、" MouseOverStoryboard "は別の名前スコープにあります。あなたの "MouseOverStoryboard"を見つけるためにFindName()メソッドを使用することができなかったコードで、この動作を変更することはできませんでした。 – Phil

+0

問題ありません。これは.NET 4.5ではまだ改善されていません。当面は回避策があることを願っています。 – erodewald

+0

いい答えです。 +1。迷惑な問題。 – cplotts

2

をジャストによる同じを有することに、このつまずい問題。もう一つの解決策がありますが、ややぎこちないものです。

別のアニメーションを適用するときにプロパティのアニメーションが上書きされるため、トリガーのExitActionsで別のBeginStoryboardを使用して前のものを上書きし、StopのFillBehaviorを使用して自動的に削除します。

残念ながら、Duration = 0、FillBehavior = Stop、およびターゲット値の組み合わせは機能しません。そのため、アニメーションに非常に短い時間を設定する必要があります。あなたの例では

<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition/> 
     <RowDefinition/> 
    </Grid.RowDefinitions> 

    <Grid.Resources> 
     <Style x:Key="rectStyle" TargetType="{x:Type Rectangle}"> 
      <Style.Triggers> 
       <Trigger Property="IsMouseOver" Value="True"> 
        <Trigger.EnterActions> 
         <BeginStoryboard> 
          <Storyboard> 
           <ColorAnimation To="PaleGoldenrod" 
            Storyboard.TargetProperty="(Fill).(Color)" 
            Duration="0:0:1"/> 
          </Storyboard> 
         </BeginStoryboard> 
        </Trigger.EnterActions> 
        <Trigger.ExitActions> 
         <BeginStoryboard> 
          <Storyboard FillBehavior="Stop"> 
           <ColorAnimation 
            Storyboard.TargetProperty="(Fill).(Color)" 
            Duration="0:0:0.0000001"/> 
          </Storyboard> 
         </BeginStoryboard> 
        </Trigger.ExitActions> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 

     <Style x:Key="rectStyle2" TargetType="{x:Type Rectangle}" 
       BasedOn="{StaticResource rectStyle}"/> 
    </Grid.Resources> 

    <Rectangle Grid.Row="0" Width="100" Height="100" Fill="Red" 
       Style="{StaticResource rectStyle}" /> 
    <Rectangle Grid.Row="1" Width="100" Height="100" Fill="Blue" 
       Style="{StaticResource rectStyle2}" /> 
</Grid> 
関連する問題