2012-03-29 26 views
4

我遇到的問題是,如果我在包含故事板的第二個樣式上創建樣式,那麼Trigger.ExitAction中存在異常。故事板名稱範圍中找不到

  • 如果我將鼠標放在下面的演示中的任意一個矩形上,那麼故事板將運行並且矩形會改變顏色。
  • 當鼠標離開具有style ='rectStyle'的紅色矩形時,故事板將被刪除。
  • 當鼠標離開藍色矩形(它使用派生的風格),我得到這個異常:

    出現InvalidOperationException: 「MouseOverStoryboard」名稱不能以「System.Windows.Style」的名稱領域中找到。

所以:

  • 有效期是有一個基本樣式故事板?
  • 是否有更明確的方式引用BeginStoryboardName以避免發生此錯誤?
  • 其他建議?

最後,我試圖實現重新使用包含其他幾種風格的觸發器和故事板的樣式。

下面是一些簡單的代碼演示該問題:

<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

最好的辦法是避開衍生款式,如果你想包括StopStoryboard。實際上有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

好,謝謝侵蝕。來自MS的信息是相似的「在WPF中,基於當前實現,這是預期的行爲,因爲每個Style類將創建它自己的實例,這意味着您的」MouseOverStoryboard「位於不同的名稱範圍內。例如,如果使用Based在樣式上,然後在後面的代碼中無法使用FindName()方法來查找「MouseOverStoryboard」,我們無法更改此行爲。「 – Phil 2012-04-11 17:19:13

+0

沒問題。在.NET 4.5中,這種羞恥感並沒有得到改善。希望你暫時有一個解決方法。 – erodewald 2012-04-12 16:02:45

+0

很好的答案。 +1。惱人的問題。 – cplotts 2014-07-29 21:40:58

2

只是偶然發現了這個因具有相同問題。還有另一種解決方案,雖然有點笨重。

當應用其他動畫時,屬性上的動畫會被覆蓋,因此您可以在觸發器的ExitActions中使用另一個BeginStoryboard來覆蓋前一個,並使用Stop的FillBehavior自動刪除該動畫。

不幸的是,持續時間= 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>