オブジェクトの現在の VisualState を取得しようとしています。SOでこれは不可能であるという回答と、別のブログで次のように取得できるはずの回答を見つけました。
var currentState = VisualStateManager.GetVisualStateGroups(ContainerGrid);
ただし、 currentState は何も取得していないようです。私は何を間違っていますか?
オブジェクトの現在の VisualState を取得しようとしています。SOでこれは不可能であるという回答と、別のブログで次のように取得できるはずの回答を見つけました。
var currentState = VisualStateManager.GetVisualStateGroups(ContainerGrid);
ただし、 currentState は何も取得していないようです。私は何を間違っていますか?
外部のものは何も必要なかったので、この回答の方がうまくいくことがわかりました: Silverlight: VisualStateManager.GetVisualStateGroups doesn't, How can I get them?
WinRT XAML Toolkit には、この拡張メソッドがあります。これ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
の一部です:
<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>
...
その視覚状態グループを抽出すると、 get によって最後に設定された状態を取得できますstateGroup.CurrentState
。
UWP XAML では、de VisualStateGroup という名前を付けるだけです。
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="PopupStates">
<VisualState x:Name="Mobile">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0"/>
</VisualState.StateTriggers>
そして、次を使用して名前を取得します。
PopupStates.CurrentState.Name