【问题标题】:Update property in ViewModel during DoubleAnimation in WPF在 WPF 中的 DoubleAnimation 期间更新 ViewModel 中的属性
【发布时间】:2014-02-07 15:41:10
【问题描述】:

我有使用 MVVM 模式的 WPF 解决方案。它包含 ViewModel BlockViewModel:

public class BlockViewModel:ViewModelBase
{
    private double _top;
    public double Top
    {
        get
        {
            return _top;
        }
        set
        {
            if (_top == value)
            {
                return;
            }
            _top = value;
            OnPropertyChanged("Top");
        }
    }

    private bool _isAnimated;
    public bool IsAnimated
    {
        get { return _isAnimated; }
        set
        {
            if (_isAnimated == value)
            {
                return;
            }
            _isAnimated = value;
            OnPropertyChanged("IsAnimated");
        }
    }

}

和用户控件BlockView:

<UserControl 
             x:Class="BlockGame.Wpf.Views.BlockView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:converters="clr-namespace:BlockGame.Wpf.Converters"
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
             xmlns:blocks="clr-namespace:BlockGame.ViewModels.Blocks;assembly=BlockGame.ViewModels"

             mc:Ignorable="d"
             d:DataContext="{d:DesignInstance Type=blocks:BlockViewModel, IsDesignTimeCreatable=True}"
             >
    <UserControl.Resources>
        <Storyboard x:Key="BlockStoryboard">
            <DoubleAnimation x:Name="StoryboardAnimation" Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)" Storyboard.TargetName="Border" From="0" To="100" Duration="0:0:5" />
        </Storyboard>

    </UserControl.Resources>

    <Border Width="100" Height="50" Name="Border" Background="Lavender" BorderThickness="1" BorderBrush="Black">

        <Border.RenderTransform>
            <TranslateTransform X="20" Y="{Binding Top}" />
        </Border.RenderTransform>

        <i:Interaction.Triggers>
            <ei:DataTrigger Binding="{Binding IsAnimated}" Value="True">
                <ei:ControlStoryboardAction Storyboard="{StaticResource BlockStoryboard}" />
            </ei:DataTrigger>
            <ei:DataTrigger Binding="{Binding IsAnimated}" Value="False">
                <ei:ControlStoryboardAction Storyboard="{StaticResource BlockStoryboard}" ControlStoryboardOption="Pause" />
            </ei:DataTrigger>
        </i:Interaction.Triggers>

    </Border>
</UserControl>

有没有办法在动画期间更新 Top 属性?

更新

看来我找到了可行的解决方案:

<Border.RenderTransform>
    <TranslateTransform X="{Binding Left}" Y="0" x:Name="TranslateTransform" />
</Border.RenderTransform>
<i:Interaction.Triggers>
         ...
    <ei:PropertyChangedTrigger Binding="{Binding ElementName=TranslateTransform, Path=Y}">
        <ei:ChangePropertyAction Value="{Binding ElementName=TranslateTransform, Path=Y}" PropertyName="Top" TargetObject="{Binding RelativeSource={RelativeSource  FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext}"></ei:ChangePropertyAction>
    </ei:PropertyChangedTrigger>
</i:Interaction.Triggers>

【问题讨论】:

    标签: c# wpf animation mvvm binding


    【解决方案1】:

    有趣的问题。 WPF 中的动画以依赖属性为目标,当您启动它们时,没有一种不时干预的好方法。一种方法是为您的动画使用自定义时间线。这允许您为动画定义自己的计时机制。同样,我自己还没有尝试过。

    查看您的代码,我看到 Top 属性绑定到边框的 Y 属性。因此,更改 top 属性实际上可能只是更改边框渲染转换的 Y 属性。

    您为什么不直接为边框制作动画,而不是制作动画并尝试在此过程中更改 Top。如果您想将您的边框动画与另一个动画同步,您可以创建两个具有相似 To、From 和 Interval 设置的双动画对象。您可以同时启动两者以达到您想要的效果。

    这是一个例子:

    ScaleTransform st = new ScaleTransform();
    this.RenderTransformOrigin = new Point(0.5, 0.5);
    this.RenderTransform = st;
    st.BeginAnimation(ScaleTransform.ScaleXProperty, scaleUp);
    st.BeginAnimation(ScaleTransform.ScaleYProperty, scaleUp);
    

    在这里,我将相同的动画应用于同一变换的两个不同属性,以按比例缩放某些东西。你可以对对象和它的边框元素做同样的事情

    【讨论】:

    • 更改此属性非常重要,因为在 Top 属性的 setter 中还有一些额外的方法可以操作其他属性。 >>查看您的代码,我看到 Top 属性绑定到边框的 Y 属性。没问题,我可以去掉这个绑定。
    猜你喜欢
    • 2010-10-31
    • 1970-01-01
    • 2012-05-28
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多