gpt4 book ai didi

wpf - VisualStateManager和生成的过渡

转载 作者:行者123 更新时间:2023-12-04 04:13:42 26 4
gpt4 key购买 nike

就在我认为我理解VisualStateManager时,就证明了我错了。

我正在使用WPF 4,并且尝试在鼠标悬停时简单地放大一个项目,并在鼠标离开时将其缩小。我想我只是要在VisualStateGroup中定义每个状态,然后用VisualTransition指定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秒钟的过程中,应将 ScaleTransform属性从1设置为1.5。鼠标移开也一样。而是有1秒的延迟,然后 ScaleTransform属性立即捕捉到1.5或回到1。

如果我按如下方式手动指定转换,那么我将获得所需的行为:
<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>

但是,为什么我必须这样做呢?我认为生成的过渡的全部要点是,过渡将是已生成的。我在这里误会什么?

更新:根据Rick的回答,Blend会生成有效的东西。因此,向后工作,我确定的确是我直接引用 ScaleTransform而不是通过包含它的 UIElement引用的事实。我将XAML更改为以下内容,并且可以按预期工作:
<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>

似乎很荒谬(和明显的错误),但它可以工作。

谢谢

最佳答案

我不能说我完全理解为什么它不按我们期望的方式工作,但是在这种情况下,我们可以使用Expression Blend来执行任务并查看其产生的标记。我已经完成了,这是一个基于您的示例的工作示例:

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

尽管Blend使用的是更通用的变换组,但我们可以看到的主要区别是, Storyboard 以一个元素为目标,并通过该元素到达比例因子的属性路径。

关于wpf - VisualStateManager和生成的过渡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4828038/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com