2013-01-31 68 views
2

我想獲取一個對象的當前VisualState。我找到了答案上,使這是不可能的,而另一個博客在其他地方,我應該能夠得到這些像這樣:在WinRT中獲取當前的VisualState

var currentState = VisualStateManager.GetVisualStateGroups(ContainerGrid); 

然而curentState似乎並沒有得到任何東西。我究竟做錯了什麼?

回答

1

的WinRT的XAML工具包具有這種擴展方法 - AwaitableUI.ControlExtensions.GoToVisualStateAsync(),使用你所提到的方法(VisualStateManager.GetVisualStateGroups())發現故事板的視覺狀態轉換和調用定期VisualStateManager.GoToState()方法後,等待其完成。到目前爲止,它對我來說工作得很好。唯一值得注意的是,你需要在指定可視狀態組的元素上調用GetVisualStateGroups(),所以在大多數情況下,你可能需要深入研究控制模板的可視樹,因爲這是他們通常定義的地方 - 在模板比實際的邏輯控制。

這裏是我的全樣本類:

using System; 
using System.Linq; 
using System.Threading.Tasks; 
using Windows.UI.Xaml; 
using Windows.UI.Xaml.Controls; 
using Windows.UI.Xaml.Media.Animation; 

namespace WinRTXamlToolkit.AwaitableUI 
{ 
    /// <summary> 
    /// Extension methods for Control class. 
    /// </summary> 
    public static class ControlExtensions 
    { 
     #region GoToVisualStateAsync() 
     /// <summary> 
     /// Goes to specified visual state, waiting for the transition to complete. 
     /// </summary> 
     /// <param name="control"> 
     /// Control to transition. 
     /// </param> 
     /// <param name="visualStatesHost"> 
     /// FrameworkElement that defines the visual states 
     /// (usually the root of the control's template). 
     /// </param> 
     /// <param name="stateGroupName"> 
     /// Name of the state group 
     /// (speeds up the search for the state transition storyboard). 
     /// </param> 
     /// <param name="stateName"> 
     /// State to transition to. 
     /// </param> 
     /// <returns> 
     /// Awaitable task that completes when the transition storyboard completes. 
     /// </returns> 
     /// <remarks> 
     /// If a state transition storyboard is not found - the task 
     /// completes immediately. 
     /// </remarks> 
     public static async Task GoToVisualStateAsync(
      this Control control, 
      FrameworkElement visualStatesHost, 
      string stateGroupName, 
      string stateName) 
     { 
      var tcs = new TaskCompletionSource<Storyboard>(); 

      Storyboard storyboard = 
       GetStoryboardForVisualState(visualStatesHost, stateGroupName, stateName); 

      if (storyboard != null) 
      { 
       EventHandler<object> eh = null; 

       eh = (s, e) => 
       { 
        storyboard.Completed -= eh; 
        tcs.SetResult(storyboard); 
       }; 

       storyboard.Completed += eh; 
      } 

      VisualStateManager.GoToState(control, stateName, true); 

      if (storyboard == null) 
      { 
       return; 
      } 

      await tcs.Task; 
     } 
     #endregion 

     #region GetStoryboardForVisualState() 
     /// <summary> 
     /// Gets the state transition storyboard for the specified state. 
     /// </summary> 
     /// <param name="visualStatesHost"> 
     /// FrameworkElement that defines the visual states 
     /// (usually the root of the control's template). 
     /// </param> 
     /// <param name="stateGroupName"> 
     /// Name of the state group 
     /// (speeds up the search for the state transition storyboard). 
     /// </param> 
     /// <param name="stateName"> 
     /// State to transition to. 
     /// </param> 
     /// <returns>The state transition storyboard.</returns> 
     private static Storyboard GetStoryboardForVisualState(
      FrameworkElement visualStatesHost, 
      string stateGroupName, 
      string stateName) 
     { 
      Storyboard storyboard = null; 

      var stateGroups = VisualStateManager.GetVisualStateGroups(visualStatesHost); 
      VisualStateGroup stateGroup = null; 

      if (!string.IsNullOrEmpty(stateGroupName)) 
      { 
       stateGroup = stateGroups.FirstOrDefault(g => g.Name == stateGroupName); 
      } 

      VisualState state = null; 

      if (stateGroup != null) 
      { 
       state = stateGroup.States.FirstOrDefault(s => s.Name == stateName); 
      } 

      if (state == null) 
      { 
       foreach (var group in stateGroups) 
       { 
        state = group.States.FirstOrDefault(s => s.Name == stateName); 

        if (state != null) 
        { 
         break; 
        } 
       } 
      } 

      if (state != null) 
      { 
       storyboard = state.Storyboard; 
      } 

      return storyboard; 
     } 
     #endregion 
    } 
} 

這是我怎麼稱呼它:

await this.GoToVisualStateAsync(_layoutRoot, PopupStatesGroupName, OpenPopupStateName); 

哪裏this是我InputDialog控制_layoutRoot是這樣定義它的template的一部分:

<Setter 
    Property="Template"> 
    <Setter.Value> 
     <ControlTemplate 
      TargetType="controls:InputDialog"> 
      <Grid 
       x:Name="LayoutRoot" 
       Background="{TemplateBinding BackgroundScreenBrush}"> 
       <VisualStateManager.VisualStateGroups> 
        <VisualStateGroup 
         x:Name="PopupStates"> 
         <VisualState 
          x:Name="OpenPopupState"> 
          <Storyboard> 
... 

一旦你通過獲得stateGroup.CurrentState xtract該視覺狀態組,你可以得到最後的設置狀態。

+0

什麼是一個很棒的工具包。感謝您指出! –

1

在UWP XAML僅舉德VisualStateGroup:

<VisualStateManager.VisualStateGroups> 
      <VisualStateGroup x:Name="PopupStates"> 
       <VisualState x:Name="Mobile"> 
        <VisualState.StateTriggers> 
         <AdaptiveTrigger MinWindowWidth="0"/> 
        </VisualState.StateTriggers> 

,你會得到使用名稱:

PopupStates.CurrentState.Name