我想獲取一個對象的當前VisualState。我找到了答案上,使這是不可能的,而另一個博客在其他地方,我應該能夠得到這些像這樣:在WinRT中獲取當前的VisualState
var currentState = VisualStateManager.GetVisualStateGroups(ContainerGrid);
然而curentState似乎並沒有得到任何東西。我究竟做錯了什麼?
我想獲取一個對象的當前VisualState。我找到了答案上,使這是不可能的,而另一個博客在其他地方,我應該能夠得到這些像這樣:在WinRT中獲取當前的VisualState
var currentState = VisualStateManager.GetVisualStateGroups(ContainerGrid);
然而curentState似乎並沒有得到任何東西。我究竟做錯了什麼?
我發現這個答案更好地工作對我來說,因爲我沒有什麼需要外部:Silverlight: VisualStateManager.GetVisualStateGroups doesn't, How can I get them?
的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
xtract該視覺狀態組,你可以得到最後的設置狀態。
在UWP XAML僅舉德VisualStateGroup:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="PopupStates">
<VisualState x:Name="Mobile">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0"/>
</VisualState.StateTriggers>
,你會得到使用名稱:
PopupStates.CurrentState.Name
什麼是一個很棒的工具包。感謝您指出! –