WP7 VisualState以编程方式更改
本文关键字:方式更 编程 VisualState WP7 | 更新日期: 2023-09-27 17:58:56
我正在尝试创建一个图像,当它被触摸时,会出现一个小弹出窗口。当你再次触摸它(或在外面的任何地方)时,它应该会消失
我已经创建了弹出窗口,以及一些隐藏和折叠的视觉状态转换
<Grid x:Name="LayoutRoot" Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="PopupVisibility">
<VisualState x:Name="PopupVisible">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="PopupControl">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="PopupControl">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="PopupControl">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="PopupControl">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="PopupCollapsed">
<Storyboard>
<DoubleAnimation Duration="0:0:0.5" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="PopupControl" d:IsOptimized="True"/>
<DoubleAnimation Duration="0:0:0.5" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="PopupControl" d:IsOptimized="True"/>
<DoubleAnimation Duration="0:0:0.5" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="PopupControl" d:IsOptimized="True"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="PopupControl">
<DiscreteObjectKeyFrame KeyTime="0:0:0.5">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:0.7">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Button Content="Text" HorizontalAlignment="Right" Margin="0,0,12,-37" Width="152" Background="#00C06B6B" Height="75" VerticalAlignment="Bottom" Visibility="Visible">
<Custom:Interaction.Triggers>
<Custom:EventTrigger EventName="Click">
<ic:GoToStateAction x:Name="GoToStatePopupVisible" StateName="PopupVisible"/>
</Custom:EventTrigger>
<Custom:EventTrigger EventName="LostFocus">
<ic:GoToStateAction x:Name="LostFocus" StateName="PopupCollapsed"/>
</Custom:EventTrigger>
</Custom:Interaction.Triggers>
</Button>
<Grid x:Name="PopupControl" Height="241" Margin="39,-28,203,0" Grid.Row="1" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<CompositeTransform/>
</Grid.RenderTransform>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF726969" Offset="1"/>
<GradientStop Color="White"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<TextBlock TextWrapping="Wrap" Text="TextBlock" d:LayoutOverrides="Width" Foreground="#FF1D0E0E" Margin="5"/>
</Grid>
<Image HorizontalAlignment="Right" Height="100" Margin="0,-38,37,0" Grid.Row="1" VerticalAlignment="Top" Width="100" Source="Images/pushpin.jpg" ManipulationStarted="Image_ManipulationStarted">
</Image>
</Grid>
我尝试使用Blend来测试这一点,效果很好,例如,添加一个按钮并创建一个事件触发器:
<Button Content="Text" HorizontalAlignment="Right" Margin="0,0,12,-37" Width="152" Background="#00C06B6B" Height="75" VerticalAlignment="Bottom" Visibility="Visible">
<Custom:Interaction.Triggers>
<Custom:EventTrigger EventName="Click">
<ic:GoToStateAction x:Name="GoToStatePopupVisible" StateName="PopupVisible"/>
</Custom:EventTrigger>
<Custom:EventTrigger EventName="LostFocus">
<ic:GoToStateAction x:Name="LostFocus" StateName="PopupCollapsed"/>
</Custom:EventTrigger>
</Custom:Interaction.Triggers>
</Button>
然而,当尝试"真实"的东西时,我需要更多的逻辑。如果我按下图像,它是可见的,我希望它过渡到塌陷,反之亦然。所以我保存了我当前的可见性状态
(VisualStateManager.GetVisualStateGroups(LayoutRoot)[0] as VisualStateGroup).CurrentStateChanged += new EventHandler<VisualStateChangedEventArgs>(MainPage_CurrentStateChanged);
public string CurrentState { get; set; }
void MainPage_CurrentStateChanged(object sender, VisualStateChangedEventArgs e)
{
CurrentState = e.NewState.Name;
}
然后我创建图像:
<Image HorizontalAlignment="Right" Height="100" Margin="0,-38,37,0" Grid.Row="1" VerticalAlignment="Top" Width="100" Source="Images/pushpin.jpg" ManipulationStarted="Image_ManipulationStarted">
</Image>
最后,我通过编程尝试做与事件触发器相同的事情,但有一些逻辑:
private void Image_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
{
switch (CurrentState)
{
case "PopupVisible":
{
ExtendedVisualStateManager.GoToElementState(LayoutRoot, "PopupCollapsed", true);
break;
}
case "PopupCollapsed":
{
ExtendedVisualStateManager.GoToElementState(LayoutRoot, "PopupVisible", true);
break;
}
}
}
我尝试了VisualStateManager和ExtendedVisualStateManager方法GoToState和GoToElementState,但都没有成功。方法总是返回false,并且屏幕上没有任何更改。我做错了什么??
我假设您调试了代码,这样您就知道控件进入了ManipulationSTarted处理程序。
Acc。到msdn VisualStateManager.GoToState文档:"如果控件的ControlTemplate中不存在stateName,GoToState不采取任何操作并返回false。"
从上面的代码中,我无法判断LayoutRoot是什么,以及状态是否真的在该元素中定义。(附带说明:Popup对视觉树进行了一些操作,在某些情况下可以解释上述行为。)
另一方面,我不明白你为什么在这种情况下使用Xaml。在我看来,你可以在代码中做得容易得多。(不谈性能。):
-
在代码中创建2个情节串连板
-
根据需要从ManipulationStarted处理程序运行它们。
如果你不知道如何在代码中使用Storyboards,可以看看我的这篇文章。