VisualStateManager和生成过渡 [英] VisualStateManager and generated transitions

查看:164
本文介绍了VisualStateManager和生成过渡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正当我想我明白了 VisualStateManager ,什么证明我错了。

Just when I think I understand the VisualStateManager, something proves me wrong.

我使用WPF 4,我试图简单地在放大鼠标的项目,和收缩回来的鼠标离开。我想我只是在一个 VisualStateGroup 定义每个状态,然后指定 VisualTransition GeneratedDuration

I'm using WPF 4 and am trying to simply enlarge an item on mouse over, and shrink it back on mouse leave. I figured I'd just define each state in a VisualStateGroup and then specify a VisualTransition with a GeneratedDuration:

<Border x:Name="PART_Root" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" RenderTransformOrigin="0.5,0.5">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup Name="CommonStates">
            <VisualStateGroup.Transitions>
                <VisualTransition GeneratedDuration="0:0:1"/>
            </VisualStateGroup.Transitions>

            <VisualState Name="Normal"/>

            <VisualState Name="MouseOver">
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleX" To="1.5" Duration="0"/>
                    <DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleY" To="1.5" Duration="0"/>
                </Storyboard>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

    <Border.RenderTransform>
        <ScaleTransform x:Name="scaleTransform" ScaleX="1" ScaleY="1"/>
    </Border.RenderTransform>

    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>

因为我有一个包罗万象的 VisualTransition GeneratedDuration ,我期待的VSM生成中间动画。也就是说,将鼠标移至应控制在1秒的过程中动画从1 ScaleTransform 属性1.5。同样的,捕鼠了。相反,有1秒的延迟,然后 ScaleTransform 性能瞬间捕捉到1.5或回1。

Since I have a catch-all VisualTransition with a GeneratedDuration, I was expecting the VSM to generate intermediate animations. That is, mousing over the control should animate the ScaleTransform properties from 1 to 1.5 over the course of 1 second. Same with mousing off. Instead, there's a delay of 1 second and then the ScaleTransform properties instantly snap to 1.5 or back to 1.

如果我手动指定作为过渡,然后如下我得到所需的行为:

If I manually specify transitions as follows then I get the desired behavior:

<VisualStateGroup.Transitions>
    <VisualTransition From="Normal" To="MouseOver">
        <Storyboard>
            <DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleX" To="1.5" Duration="{StaticResource MouseEnterDuration}"/>
            <DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleY" To="1.5" Duration="{StaticResource MouseEnterDuration}"/>
        </Storyboard>
    </VisualTransition>

    <VisualTransition From="MouseOver" To="Normal">
        <Storyboard>
            <DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleX" To="1" Duration="{StaticResource MouseLeaveDuration}"/>
            <DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleY" To="1" Duration="{StaticResource MouseLeaveDuration}"/>
        </Storyboard>
    </VisualTransition>
</VisualStateGroup.Transitions>

但为什么我要这么做?我想产生转换的整点是,转型将是,你知道的,产生的。什么我误解吗?

But why do I have to do this? I thought the whole point of generated transitions was that the transition would be, you know, generated. What am I misunderstanding here?

更新:按照里克的回答,混合生成的的东西确实的工作。因此,工作向后我确定它的确是我引用的事实, ScaleTransform ,而不是直接通过的UIElement 包含它。我改变了我的XAML以下内容,它按预期工作:

UPDATE: As per Rick's answer, Blend generates something that does work. Thus, working backwards I determined that it is indeed the fact that I'm referencing the ScaleTransform directly rather than through the UIElement that contains it. I changed my XAML to the following and it works as expected:

<Border x:Name="PART_Root" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" RenderTransformOrigin="0.5,0.5">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup Name="CommonStates">
            <VisualStateGroup.Transitions>
                <VisualTransition From="Normal" To="MouseOver" GeneratedDuration="{StaticResource MouseEnterDuration}"/>

                <VisualTransition From="MouseOver" To="Normal" GeneratedDuration="{StaticResource MouseLeaveDuration}"/>
            </VisualStateGroup.Transitions>

            <VisualState Name="Normal"/>

            <VisualState Name="MouseOver">
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="PART_Root" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)" To="{StaticResource MouseOverScale}" Duration="0"/>
                    <DoubleAnimation Storyboard.TargetName="PART_Root" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)" To="{StaticResource MouseOverScale}" Duration="0"/>
                </Storyboard>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

    <Border.RenderTransform>
        <ScaleTransform/>
    </Border.RenderTransform>

    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>

显得很荒谬(和明显的bug),但它的工作原理。

Seems ridiculous (and an obvious bug), but it works.

感谢

推荐答案

我不能说我完全理解为什么它不工作,我们会期待它的方式,但在这种情况下,我们可以使用防爆pression混合来执行任务,看看它会产生什么样的标记。我已经做了,这里是根据样品的工作示例:

I can't say that I fully understand why it doesn't work the way we'd expect it to, but in these situations we can use Expression Blend to perform the task and see what markup it produces. I've done that and here's a working example based on your sample:

<Grid>
    <Grid.Resources>
        <Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Border x:Name="PART_Root" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" RenderTransformOrigin="0.5,0.5">
                            <Border.RenderTransform>
                                <TransformGroup>
                                    <ScaleTransform/>
                                    <SkewTransform/>
                                    <RotateTransform/>
                                    <TranslateTransform/>
                                </TransformGroup>
                            </Border.RenderTransform>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup Name="CommonStates">
                                    <VisualStateGroup.Transitions>
                                        <VisualTransition GeneratedDuration="0:0:1"/>
                                    </VisualStateGroup.Transitions>
                                    <VisualState Name="Normal"/>
                                    <VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="PART_Root">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="2"/>
                                            </DoubleAnimationUsingKeyFrames>
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="PART_Root">
                                                <EasingDoubleKeyFrame KeyTime="0" Value="2"/>
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Grid.Resources>
    <Button Content="Button" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75" Style="{StaticResource ButtonStyle1}"/>
</Grid>

虽然混合使用更一般的变换组中,我们可以看到的主要区别在于,在故事板的目标元素,并通过该元素的比例因子属性路径

Although Blend uses a more general transform group, the main difference we can see is that the storyboard targets an element and a property path through that element to the scaling factors.

这篇关于VisualStateManager和生成过渡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆