开发者

WP7 VisualState change programmatically

I'm trying to create an Image, that when it's touched, a small popup appears. When you touch it again (or anywhere outside) it should dissapear.

I've created the popup, and some visual state transitions to hide and collapse

<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&g开发者_JAVA百科t;
                                    </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>

I tried using Blend to test this, and works fine, for example, adding a button and creating an eventtrigger :

<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>

However, when trying the "real" thing, I need more logic than this. If I press the image and it's visible, i want it to transition to collapsed, and viceversa. So I save my current visibility state

(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;
        }

And then i create the image :

<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>

Finally, I programmatically try to do the same thing than the eventtrigger does, but with some logic :

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;
                    }
            }
        }

I tried both VisualStateManager and ExtendedVisualStateManager methods GoToState and GoToElementState, but to no avail. The methods always return false and nothing changes on the screen. What am i doing wrong??


I presume that you debugged the code so you know that the control gets to ManipulationSTarted handler.

Acc. to msdn VisualStateManager.GoToState documentation: "If stateName doesn't exist in the ControlTemplate of control, GoToState takes no action and returns false."

From the above code I am not able to judge what's the LayoutRoot and whether the states are really defined at that element. (A side remark: Popup does some manipulation of the visual tree, which in some cases could explain above behavior.)

On the other hand, I don't understand why you use Xaml in this case. In my opinion you can do it much easier in the code. (Not to speak about the performance.):

  1. Create 2 storyboards in the code

  2. Run them as needed from ManipulationStarted handler.

If you don't know how to work with Storyboards in the code, look for example at this my article.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜