VisualStateManager.GoToState useTransitions 在自定义控件 UWP 中被忽略
VisualStateManager.GoToState useTransitions Ignored in custom control UWP
我创建了一个继承自 contentControl
的自定义控件。该控件在从打开变为关闭时使用 PlaneProjection.RotationX
动画,反之亦然。
我希望控件初始状态为关闭状态。当应用程序启动时,即使我设置了 changeVisualState(false)
.
,也会显示从打开到关闭的过渡
我做错了什么?
我的代码:
public sealed class FlipPanel : ContentControl
{
private VisualState collapsedState;
private FrameworkElement contentElement;
public FlipPanel()
{
this.DefaultStyleKey = typeof(FlipPanel);
}
public bool IsOpen
{
get { return (bool)GetValue(IsOpenProperty); }
set { SetValue(IsOpenProperty, value); }
}
public static readonly DependencyProperty IsOpenProperty =
DependencyProperty.Register("IsOpen", typeof(bool), typeof(FlipPanel), new PropertyMetadata(false, onIsOpenChanged));
private static void onIsOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FlipPanel flipPanel = d as FlipPanel;
flipPanel.changeVisualState(true);
}
private void changeVisualState(bool useTransitions)
{
Debug.WriteLine(IsOpen.ToString());
if (IsOpen)
{
if (contentElement != null)
{
contentElement.Visibility = Visibility.Visible;
}
VisualStateManager.GoToState(this, "Opening", useTransitions);
}
else
{
VisualStateManager.GoToState(this, "Closing", useTransitions);
}
}
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
contentElement = (FrameworkElement)GetTemplateChild("Content");
if (contentElement != null)
{
collapsedState = (VisualState)GetTemplateChild("Closing");
if ((collapsedState != null) && (collapsedState.Storyboard != null))
{
collapsedState.Storyboard.Completed += (object sender, object e) =>
{
contentElement.Visibility = Visibility.Collapsed;
};
}
changeVisualState(false);
}
}
}
和我的Style
<Style TargetType="local:FlipPanel" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:FlipPanel">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ViewStates">
<VisualState x:Name="Opening">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)" Storyboard.TargetName="Content">
<EasingDoubleKeyFrame KeyTime="0" Value="-90"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Closing">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)" Storyboard.TargetName="Content">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="90"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter Content="{TemplateBinding Content}" x:Name="Content">
<ContentPresenter.Projection>
<PlaneProjection CenterOfRotationX="0.5"/>
</ContentPresenter.Projection>
</ContentPresenter>
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我认为这是因为你在故事板的 Completed
事件中使 Content
折叠起来,然后设置 changeVisualState(false);
,它不会做任何事情,因为 "closing" 故事板完成。
我像这样修改了您的 OnApplyTemplate
代码并且它有效:
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
contentElement = (FrameworkElement)GetTemplateChild("Content");
if (contentElement != null)
{
if (!IsOpen)
contentElement.Visibility = Visibility.Collapsed;
else
changeVisualState(true);
}
}
我创建了一个继承自 contentControl
的自定义控件。该控件在从打开变为关闭时使用 PlaneProjection.RotationX
动画,反之亦然。
我希望控件初始状态为关闭状态。当应用程序启动时,即使我设置了 changeVisualState(false)
.
我做错了什么?
我的代码:
public sealed class FlipPanel : ContentControl
{
private VisualState collapsedState;
private FrameworkElement contentElement;
public FlipPanel()
{
this.DefaultStyleKey = typeof(FlipPanel);
}
public bool IsOpen
{
get { return (bool)GetValue(IsOpenProperty); }
set { SetValue(IsOpenProperty, value); }
}
public static readonly DependencyProperty IsOpenProperty =
DependencyProperty.Register("IsOpen", typeof(bool), typeof(FlipPanel), new PropertyMetadata(false, onIsOpenChanged));
private static void onIsOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FlipPanel flipPanel = d as FlipPanel;
flipPanel.changeVisualState(true);
}
private void changeVisualState(bool useTransitions)
{
Debug.WriteLine(IsOpen.ToString());
if (IsOpen)
{
if (contentElement != null)
{
contentElement.Visibility = Visibility.Visible;
}
VisualStateManager.GoToState(this, "Opening", useTransitions);
}
else
{
VisualStateManager.GoToState(this, "Closing", useTransitions);
}
}
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
contentElement = (FrameworkElement)GetTemplateChild("Content");
if (contentElement != null)
{
collapsedState = (VisualState)GetTemplateChild("Closing");
if ((collapsedState != null) && (collapsedState.Storyboard != null))
{
collapsedState.Storyboard.Completed += (object sender, object e) =>
{
contentElement.Visibility = Visibility.Collapsed;
};
}
changeVisualState(false);
}
}
}
和我的Style
<Style TargetType="local:FlipPanel" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:FlipPanel">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ViewStates">
<VisualState x:Name="Opening">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)" Storyboard.TargetName="Content">
<EasingDoubleKeyFrame KeyTime="0" Value="-90"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Closing">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)" Storyboard.TargetName="Content">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="90"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter Content="{TemplateBinding Content}" x:Name="Content">
<ContentPresenter.Projection>
<PlaneProjection CenterOfRotationX="0.5"/>
</ContentPresenter.Projection>
</ContentPresenter>
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我认为这是因为你在故事板的 Completed
事件中使 Content
折叠起来,然后设置 changeVisualState(false);
,它不会做任何事情,因为 "closing" 故事板完成。
我像这样修改了您的 OnApplyTemplate
代码并且它有效:
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
contentElement = (FrameworkElement)GetTemplateChild("Content");
if (contentElement != null)
{
if (!IsOpen)
contentElement.Visibility = Visibility.Collapsed;
else
changeVisualState(true);
}
}