我正在尝试获取对象的当前VisualState。我找到了一个答案,这是不可能的,另一个博客在其他地方,我应该能够得到这样的:
var currentState = VisualStateManager.GetVisualStateGroups(ContainerGrid);
然而,curentState似乎没有得到任何东西。我做错了什么?
答案 0 :(得分:2)
我发现这个答案对我来说更好,因为我不需要任何外在的东西:Silverlight: VisualStateManager.GetVisualStateGroups doesn't, How can I get them?
答案 1 :(得分: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
来获取最后设置状态。
答案 2 :(得分:1)
在UWP XAML中,只需命名为VisualStateGroup:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="PopupStates">
<VisualState x:Name="Mobile">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0"/>
</VisualState.StateTriggers>
你得到的名字是:
PopupStates.CurrentState.Name