所以我的 xaml 代码看起来像这样 -
<Grid x:Name="LayoutRoot">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
我无法使用 GoToVisualState
行为,因为我需要在运行此动画之前进行一些检查。所以我想我必须在后面的代码中调用类似 GoToState
或 GoToElementState
的东西。
但是,ExtendedVisualStateManager
似乎在 WinRT 中不存在。我尝试使用
VisualStateManager.GetCustomVisualStateManager(this.LayoutRoot)
但它总是返回null
。
有什么解决办法吗?
最佳答案
刚刚想通了。
首先创建一个帮助器类,就像我们过去在 Silverlight 或 Windows Phone 中使用它一样(我从 here 中获取了这段代码并对其进行了一些修改,以便当元素没有任何视觉状态组时连接后,它会自动搜索其父级,直到找到为止)。
public class ExtendedVisualStateManager : VisualStateManager
{
protected override bool GoToStateCore(Control control, FrameworkElement stateGroupsRoot, string stateName, VisualStateGroup group, VisualState state, bool useTransitions)
{
if ((group == null) || (state == null))
{
return false;
}
if (control == null)
{
control = new ContentControl();
}
return base.GoToStateCore(control, stateGroupsRoot, stateName, group, state, useTransitions);
}
public static bool GoToElementState(FrameworkElement element, string stateName, bool useTransitions)
{
var root = FindNearestStatefulFrameworkElement(element);
var customVisualStateManager = VisualStateManager.GetCustomVisualStateManager(root) as ExtendedVisualStateManager;
return ((customVisualStateManager != null) && customVisualStateManager.GoToStateInternal(root, stateName, useTransitions));
}
private static FrameworkElement FindNearestStatefulFrameworkElement(FrameworkElement element)
{
while (element != null && VisualStateManager.GetCustomVisualStateManager(element) == null)
{
element = element.Parent as FrameworkElement;
}
return element;
}
private bool GoToStateInternal(FrameworkElement stateGroupsRoot, string stateName, bool useTransitions)
{
VisualStateGroup group;
VisualState state;
return (TryGetState(stateGroupsRoot, stateName, out group, out state) && this.GoToStateCore(null, stateGroupsRoot, stateName, group, state, useTransitions));
}
private static bool TryGetState(FrameworkElement element, string stateName, out VisualStateGroup group, out VisualState state)
{
group = null;
state = null;
foreach (VisualStateGroup group2 in VisualStateManager.GetVisualStateGroups(element))
{
foreach (VisualState state2 in group2.States)
{
if (state2.Name == stateName)
{
group = group2;
state = state2;
return true;
}
}
}
return false;
}
}
然后您需要手动将 xaml 更新为类似这样的内容 -
<VisualStateManager.CustomVisualStateManager>
<common:ExtendedVisualStateManager />
</VisualStateManager.CustomVisualStateManager>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup .../>
</VisualStateManager.VisualStateGroups>
我想这个解决方案的好处是您仍然可以在 Blend 的状态选项卡中看到视觉状态,对于 Blend 爱好者来说这太酷了。
关于windows-8 - 在 Windows 应用商店应用程序的代码隐藏中转到网格内的视觉状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23697204/