【问题标题】:getting the current VisualState in WinRT在 WinRT 中获取当前的 VisualState
【发布时间】:2015-11-02 23:02:08
【问题描述】:

我正在尝试获取对象的当前 VisualState。我在 SO 上找到了一个答案,这是不可能的,在其他地方的另一个博客上我应该能够像这样得到这些:

var currentState = VisualStateManager.GetVisualStateGroups(ContainerGrid);

但是,curentState 似乎什么也没得到。我做错了什么?

【问题讨论】:

    标签: windows-runtime winrt-xaml visualstatemanager


    【解决方案1】:

    我发现这个答案对我来说效果更好,因为我不需要任何外部的东西:Silverlight: VisualStateManager.GetVisualStateGroups doesn't, How can I get them?

    【讨论】:

      【解决方案2】:

      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 来获取最后设置的状态。

      【讨论】:

        【解决方案3】:

        在 UWP XAML 中,只需命名 de VisualStateGroup:

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

        你得到的名字使用:

        PopupStates.CurrentState.Name
        

        【讨论】:

          猜你喜欢
          • 2012-04-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多