【问题标题】:Wpf animation with mvvm pattern带有 mvvm 模式的 Wpf 动画
【发布时间】:2013-10-03 09:17:04
【问题描述】:

动画工作的小例子,不适用于动画的模型属性变化

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="440" Width="732" Loaded="Window_Loaded"
    MouseLeftButtonDown="Grid_MouseLeftButtonDown" MouseLeftButtonUp="Grid_MouseLeftButtonUp" MouseMove="Grid_MouseMove">
<Window.Resources>

</Window.Resources>
<Grid>        
    <Grid.RowDefinitions>
        <RowDefinition Height="20"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
        <RowDefinition Height="20"></RowDefinition>
    </Grid.RowDefinitions>        
    <Canvas Name="canvMain" Height="360" Width="710" Grid.Row="1">
        <Rectangle Name="Zombi" Width="20" Height="40" Stroke="Black" StrokeThickness="2" Canvas.Bottom="0" Canvas.Right="{Binding Path=X, UpdateSourceTrigger=PropertyChanged, NotifyOnTargetUpdated=True}"></Rectangle>
    </Canvas>
</Grid>

public double X
    {
        get { return _x; }
        set
        {
            if (!double.IsNaN(value))
            {
                _x = value;
                OnPropertyChanged("X");
            }
        }
    }

double pixelMetr = 0.715;

    private int GetPixel(double metr)
    {
        return Convert.ToInt32(metr / pixelMetr);
    }

private void StartZombi()
    {
        double distance = 250;
        double maxTime = (new Random()).Next(5, 10);

        PathGeometry animationPath = new PathGeometry();

        LineGeometry lineGeometry = new LineGeometry();
        lineGeometry.StartPoint = new Point(0, 0);
        lineGeometry.EndPoint = new Point(GetPixel(distance), 0);

        animationPath.AddGeometry(lineGeometry);

        DoubleAnimationUsingPath animationX = new DoubleAnimationUsingPath();
        animationX.PathGeometry = animationPath;
        animationX.Duration = TimeSpan.FromSeconds(maxTime);
        animationX.Source = PathAnimationSource.X;
        Storyboard.SetTarget(animationX, Zombi);
        Storyboard.SetTargetProperty(animationX, new PropertyPath(Canvas.RightProperty));

        Storyboard pathAnimationStoryboard = new Storyboard();
        pathAnimationStoryboard.RepeatBehavior = RepeatBehavior.Forever;
        pathAnimationStoryboard.Children.Add(animationX);

        pathAnimationStoryboard.Begin(this);
    }

你好为什么属性改变不起作用,我需要在动画运行时获取属性'canvas.right'的当前值。

这是 xaml 代码。

【问题讨论】:

  • TestX 是干什么用的?如果这是出于显示目的,那么您还需要通知属性更改。
  • TextX - 别注意,这只是另一个属性
  • 请显示您的 XAML 的其余部分...我什至不知道您要制作什么控件。
  • 谢谢,但我仍然无法运行您的代码。请出示您的GetPixel 方法,然后我可以正确测试它。
  • 更新,我插入了GetPixel方法

标签: wpf animation mvvm


【解决方案1】:

好的,我为您找到了解决方案...您所需要做的就是为 X 创建一个 DependencyProperty 并为其设置动画:

public static readonly DependencyProperty XProperty = DependencyProperty.
    Register("X", typeof(double), typeof(MainWindow));

public double X
{
    get { return (double)GetValue(XProperty); }
    set { SetValue(XProperty, value); }
}

那么你的动画方法:

private void StartZombi()
{
    double distance = 250;
    double maxTime = (new Random()).Next(5, 10);

    PathGeometry animationPath = new PathGeometry();

    LineGeometry lineGeometry = new LineGeometry();
    lineGeometry.StartPoint = new Point(0, 0);
    lineGeometry.EndPoint = new Point(GetPixel(distance), 0);

    animationPath.AddGeometry(lineGeometry);

    DoubleAnimationUsingPath animationX = new DoubleAnimationUsingPath();
    animationX.PathGeometry = animationPath;
    animationX.Duration = TimeSpan.FromSeconds(maxTime);
    animationX.Source = PathAnimationSource.X;
    Storyboard.SetTarget(animationX, This); // <<< 'This' is the Window.Name
    Storyboard.SetTargetProperty(animationX, 
        new PropertyPath(MainWindow.XProperty));

    Storyboard pathAnimationStoryboard = new Storyboard();
    pathAnimationStoryboard.RepeatBehavior = RepeatBehavior.Forever;
    pathAnimationStoryboard.Children.Add(animationX);

    pathAnimationStoryboard.Begin(this);
}

还有 XAML:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <Canvas Name="canvMain" Height="360" Width="710" Grid.Row="1">
        <Rectangle Name="Zombi" Width="20" Height="40" Stroke="Black" 
            StrokeThickness="2" Canvas.Bottom="60" Canvas.Right="{Binding Path=X,
            UpdateSourceTrigger=PropertyChanged}" />
    </Canvas>
    <TextBlock Grid.Row="0" FontSize="26" Text="{Binding X}" />
</Grid>

您需要做的最后一件事是将Window.Name 属性设置为"This"

要回答您最初关于为什么您的代码不起作用的问题,我不能 100% 确定,但我相信这是因为 Canvas.X 属性未插入 INotifyPropertyChanged 接口,因此您的原始从未调用 CLR X 属性设置器。当Binding 到集合的Count 属性时也有类似的情况......当您将项目添加到集合时它不会更新 UI,因为它不会通知更改。

【讨论】:

    猜你喜欢
    • 2012-12-27
    • 2010-12-27
    • 1970-01-01
    • 2012-04-19
    • 2016-07-12
    • 2016-02-12
    • 2011-03-31
    • 2011-09-23
    • 2017-01-14
    相关资源
    最近更新 更多