0
votes

The small example of work on animation, does not work variation of property of model, at animation

<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);
    }

Hello why does not work property change, I need to get the current value of the property ' canvas.right ', when the animation runs.

This is xaml code.

1
What is TestX for? If that is for display purposes, then you will need to notify the property change on that also.Sheridan
TextX - Do not pay attention, this is just another propertyEugene Che
Please show the rest of your XAML... I have no idea what control you are trying to animate even.Sheridan
Thank you, but I still can't run your code. Please show your GetPixel method and then I can test it properly.Sheridan
Update, i inserted GetPixel methodEugene Che

1 Answers

0
votes

OK, I found you a solution... all you need to do is to create a DependencyProperty for X and animate that instead:

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

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

Then your animation method:

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);
}

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

The last thing that you need to do to make this work is to set the Window.Name property to "This".

To answer your original question as to why your code was not working, I'm not 100% sure, but I believe that it was because the Canvas.X property is not plugged into the INotifyPropertyChanged interface and so your original CLR X property setter was never being called. There is a similar situation when Binding to the Count property of a collection... it won't update the UI when you add items to the collection, as it is not notifying the changes.