Reputation: 36070
I have the property:
double _X;
public double X
{
get {
this.Title = _X.ToString();
return _X;
}
set {
_X = value;
this.Title = _X.ToString(); // !!!! this line does not execute when property changes from storyboard
RaisePropertyChanged("X"); }
}
and the control:
<Button x:Name="button" Content="Button" HorizontalAlignment="Left" Height="99.2" Margin="37,14,0,0" VerticalAlignment="Top" Width="98.4" RenderTransformOrigin="0.5,0.5">
<Button.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform X="{Binding X}" Y="{Binding Y}"/>
</TransformGroup>
</Button.RenderTransform>
</Button>
the storyboard:
<Storyboard x:Key="Storyboard1" AutoReverse="True" FillBehavior="HoldEnd">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="button">
<EasingDoubleKeyFrame KeyTime="0:0:1.2" Value="100">
<EasingDoubleKeyFrame.EasingFunction>
<CircleEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
when I animate the property why does the set method does not change if I am implementing the INotifyPropertyChanged interface? In other words why does the line this.Title = _X.ToString();
does not execute meanwhile animating the storyboard. How can I update the X property every time the storyboard animates?
I forgot to mention the reason why I need this functionality. I often have to animate a property that is not in xaml. for example lets say I want to animate the master volume, or perhaps the mouse position. I know I can create a thread then do the math and create my own animation. but why reinvent the wheel if wpf already has several easing functions and animations. it will be nice if I could create a storyboard using expresion blend then use that storyboard to animate a property in my code behind.
According to @clemens I have worked this out (maybe I am doing something wrong):
I have the class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.ComponentModel;
using System.Windows;
namespace SomeNamespace
{
public partial class MyUserControl : UserControl, INotifyPropertyChanged
{
public static readonly DependencyProperty SomeDoubleProperty =
DependencyProperty.Register("SomeDouble", typeof(Double),
typeof(MyUserControl), new PropertyMetadata(0.0));
public double SomeDouble
{
get
{
return (double)GetValue(SomeDoubleProperty);
}
set
{
SetValue(SomeDoubleProperty, value);
MessageBox.Show("this msg should appear meanwhile animating!");
// code does not execute
RaisePropertyChanged("SomeDouble");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
I have the view
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:test="clr-namespace:SomeNamespace"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<Window.Resources>
<Storyboard x:Key="Storyboard1" >
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="SomeDouble" Storyboard.TargetName="m">
<EasingDoubleKeyFrame KeyTime="0:0:5.4" Value="100">
<EasingDoubleKeyFrame.EasingFunction>
<CircleEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Grid>
<test:MyUserControl x:Name="m" SomeDouble="5"></test:MyUserControl>
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="311,50,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
</Grid>
</Window>
and the button code behind starts the storyboard...
the property does not change in the code behind meanwhile animating it...
Upvotes: 1
Views: 643
Reputation: 128157
If i understand you right, you're going to animate the X
property of a TranslateTransform, that is also bound to your X
property (you didn't mention the class in which it is defined).
Even if you had declared the binding two-way, your approach won't work. A dependency property such as TranslateTransform.X
gets its value from a variety of providers like style setters, triggers, animations, value inheritance, default value from property metadata, local value, and a few more (where data bindings set the local value). These providers are applied in a certain order, i.e. with a certain precedence.
In your scenario this means that the RenderTransform.X
gets its local value from a data binding. When you start an animation, the effective property value comes from that animation as long as it is running or holding the value. Meanwhile the local value of the property does not change, meaning that there is no effect on the binding (even if it was two-way).
If you want to animate your X
property, you could make it a custom dependency property and animate it directly.
Upvotes: 4