2016-08-15 52 views
0

我正試圖爲Windows 10下的通用應用程序生成一個「確定的」ProgressRing,並且在使用StateTrigger時遇到問題 - 被激活後,它不會返回到之前的VisualState,而是返回到null。我會認爲這不是預期的行爲。動畫在觸發時正確發生,但在返回時不會發生。當從代碼調用...GoToState(..., "Running", ...)時,它的動畫效果與預期的一樣,無論如何,它在OnApplyTemplate期間也成功發生。StateTrigger不返回到以前的VisualState?

我曾嘗試:

<VisualStateGroup.Transitions> 
    <VisualTransition From="{x:Null}" To="Stopped" GeneratedDuration="0:0:1" /> 
    <VisualTransition From="Stopped" To="{x:Null}" GeneratedDuration="0:0:1" /> 
</VisualStateGroup.Transitions> 

期間To="Stopped"其中(令人驚訝的)的工作原理,同樣爲下面的代碼,而不是相反的期間。

我想在XAML而不是從代碼中工作。 DotNet錯誤還是我的錯?我該如何解決它?我是否需要手動恢復到「正在運行」狀態?該代碼,這會出現一個控件模板中:

<VisualStateGroup x:Name="States"> 
    <VisualStateGroup.Transitions> 
     <VisualTransition GeneratedDuration="0:0:1" /> 
    </VisualStateGroup.Transitions> 
    <VisualState x:Name="Running" /> 
    <VisualState x:Name="Stopped"> 
     <VisualState.StateTriggers> 
      <StateTrigger IsActive="{Binding ShowPaused, RelativeSource={RelativeSource TemplatedParent}}" /> 
     </VisualState.StateTriggers> 
     <Storyboard> 
      <DoubleAnimation Storyboard.TargetName="PART_Indicator" 
          Storyboard.TargetProperty="(UIElement.Opacity)" 
          To="{ThemeResource ProgressBarIndicatorPauseOpacity}"/> 
     </Storyboard> 
    </VisualState> 
</VisualStateGroup> 

回答

2

當你在代碼隱藏使用VisualStateManager.GoToState method,你的動畫作品。這是因爲在GoToState方法中,您已指定要轉換到的狀態,因此VisualStateManager系統知道要根據VisualTransition執行哪種動畫。

但是在XAML中,您使用的是StateTrigger class來指定何時應用特定的VisualState。而StateTrigger.IsActive propertytrue,VisualStateManager系統應用此VisualState。由於VisualStateManager系統知道要轉換到的狀態,因此將執行動畫。然而,雖然StateTrigger.IsActive屬性爲false,但狀態對控件的修改將被刪除,但不會觸發不同VisualState之間的更改。

因此在您的示例中,VisualTransition爲「已停止」,但StateTrigger.IsActivefalse時,沒有動畫。要解決這個問題,我們可以在「運行」狀態設置VisualState.StateTriggersInvertBoolConverter類似以下內容:

public class InvertBoolConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, string language) 
    { 
     var boolValue = (bool)value; 
     return !boolValue; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, string language) 
    { 
     var boolValue = (bool)value; 
     return !boolValue; 
    } 
} 

而在「運行」狀態:

<VisualState x:Name="Running"> 
    <VisualState.StateTriggers> 
     <StateTrigger IsActive="{Binding ShowPaused, Converter={StaticResource InvertBoolConverter}, RelativeSource={RelativeSource TemplatedParent}}" /> 
    </VisualState.StateTriggers> 
</VisualState> 

此外,在VisualTransition,該From值參考作爲當前狀態的狀態的名稱。 To值引用了作爲新狀態的狀態的名稱。並且VisualTransition可以僅參考From狀態,僅參考To狀態,或參考FromTo狀態。省略FromTo等同於任何狀態。因此,如果您不想同時設置FromTo狀態,則可以省略其中的一個,而不是將其設置爲{x:Null}

<VisualStateGroup.Transitions> 
    <VisualTransition To="Stopped" GeneratedDuration="0:0:1" /> 
    <VisualTransition From="Stopped" GeneratedDuration="0:0:1" /> 
</VisualStateGroup.Transitions> 
+0

是否'VisualStateGroup.Transitions'預計沒有'InvertBoolConverter'工作?這與使用默認的''有什麼不同?在沒有'InvertBoolConverter'的情況下,我都不能在這種情況下工作,並且都是用它做的。我仍然不明白爲什麼需要'InvertBoolConverter':不應該''照顧? –

+0

@TimRawlinson在你的情況下,'InvertBoolConverter'是必需的。 VisualStateManager系統需要知道'VisualState'已經改變,所以它可以根據'VisualTransition'執行動畫。如果我們沒有在「Runing」中設置「StateTrigger」,那麼當「ShowPaused」爲「false」時,不會改變「VisualState」。這是因爲當'StateTrigger.IsActive'屬性爲'false'時,它只是刪除狀態對控件的修改,並不會觸發'VisualState'的更改。 –