0

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

<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 代码。

4

1 回答 1

0

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

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接口,因此您的原始 CLRX属性设置器从未被调用。Binding集合的属性也有类似的情况Count......当您将项目添加到集合时,它不会更新 UI,因为它不会通知更改。

于 2013-10-03T13:55:09.747 回答