windows-8 - 在 Windows 应用商店应用程序的代码隐藏中转到网格内的视觉状态

标签 windows-8 windows-runtime windows-store-apps winrt-xaml windows-8.1

所以我的 xaml 代码看起来像这样 -

<Grid x:Name="LayoutRoot">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="CommonStates">

我无法使用 GoToVisualState 行为,因为我需要在运行此动画之前进行一些检查。所以我想我必须在后面的代码中调用类似 GoToStateGoToElementState 的东西。

但是,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/

相关文章:

c# - 异步任务没有结束

c# - Windows RT - 按钮单击事件是否在 UI 线程上执行?

c# - 我们如何通过 c# 中的 Windows 8 Share Charm 一次共享多个图像或图像与文本的组合

xaml - Windows 8 XAML 按钮隐藏 onHover,我们该如何解决?

c# - 在可移植类库中使用外部 DLL

c++ - 在 Windows 8 上使用 Windows UI 自动化列出 Metro 应用程序的所有 UI 元素

javascript - 在 Windows Javascript 应用程序中未获得正确排序的数组

c# - 如何调试 Windows 应用商店应用程序崩溃?

data-binding - WindowsRT 数据绑定(bind)如何在没有 TypeConverterAttribute 的情况下进行类型转换

windows-8 - 在 Windows 8 应用程序中禁用 snapview 中的应用栏