我的类派生自FrameworkElement
,我希望WPF使用DoubleAnimation
更新其Location属性。我将该房产注册为DependendencyProperty
:
public class TimeCursor : FrameworkElement
{
public static readonly DependencyProperty LocationProperty;
public double Location
{
get { return (double)GetValue(LocationProperty); }
set
{
SetValue(LocationProperty, value);
}
}
static TimeCursor()
{
LocationProperty = DependencyProperty.Register("Location", typeof(double), typeof(TimeCursor));
}
}
以下代码设置了故事板。
TimeCursor timeCursor;
private void SetCursorAnimation()
{
timeCursor = new TimeCursor();
NameScope.SetNameScope(this, new NameScope());
RegisterName("TimeCursor", timeCursor);
storyboard.Children.Clear();
DoubleAnimation animation = new DoubleAnimation(LeftOffset, LeftOffset + (VerticalLineCount - 1) * HorizontalGap + VerticalLineThickness,
new Duration(TimeSpan.FromMilliseconds(musicDuration)), FillBehavior.HoldEnd);
Storyboard.SetTargetName(animation, "TimeCursor");
Storyboard.SetTargetProperty(animation, new PropertyPath(TimeCursor.LocationProperty));
storyboard.Children.Add(animation);
}
然后我从包含上述storyboard.Begin(this)
方法的对象的另一个方法中调用SetCursorAnimation()
,该对象派生自Canvas
。但是Location
属性永远不会更新(从不调用Location的set访问器)并且不会抛出异常。我做错了什么?
答案 0 :(得分:1)
当依赖项属性被动画化(或在XAML中设置,或由样式设置器等设置)时,WPF不会调用CLR包装器,而是直接访问底层的DependencyObject和DependencyProperty对象。请参阅Checklist for Defining a Dependency Property中的实施“包装器”部分以及Implications for Custom Dependency Properties。
要获得有关房产更改的通知,您必须注册PropertyChangedCallback:
public class TimeCursor : FrameworkElement
{
public static readonly DependencyProperty LocationProperty =
DependencyProperty.Register(
"Location", typeof(double), typeof(TimeCursor),
new FrameworkPropertyMetadata(LocationPropertyChanged)); // register callback here
public double Location
{
get { return (double)GetValue(LocationProperty); }
set { SetValue(LocationProperty, value); }
}
private static void LocationPropertyChanged(
DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var timeCursor = obj as TimeCursor;
// handle Location property changes here
...
}
}
另请注意,为依赖项属性设置动画并不一定需要Storyboard。您只需在TimeCursor实例上调用BeginAnimation方法:
var animation = new DoubleAnimation(LeftOffset,
LeftOffset + (VerticalLineCount - 1) * HorizontalGap + VerticalLineThickness,
new Duration(TimeSpan.FromMilliseconds(musicDuration)),
FillBehavior.HoldEnd);
timeCursor.BeginAnimation(TimeCursor.LocationProperty, animation);