自定义控件上的WPF PropertyPath

时间:2017-07-18 19:40:27

标签: wpf animation propertypath

我遇到了问题,我创建了一个名为Tile的控件(就像Windows 10上的Tile一样)。 此图块通过使用投影类来模拟旋转3D,就像Silverlight中的投影类一样。

我们有一个像这样的基础投影类:

abstract public class Projection
    : FrameworkElement
{
    static public readonly DependencyProperty RotationZProperty = DependencyProperty.Register(
          nameof(RotationZ),
          typeof(double),
          typeof(Projection),
          new UIPropertyMetadata(0.0, OnRotationChanged));

    static public readonly DependencyProperty RotationYProperty = DependencyProperty.Register(
            nameof(RotationY),
            typeof(double),
            typeof(Projection),
            new UIPropertyMetadata(0.0, OnRotationChanged));

    static public readonly DependencyProperty RotationXProperty = DependencyProperty.Register(
            nameof(RotationX),
            typeof(double),
            typeof(Projection),
            new UIPropertyMetadata(0.0, OnRotationChanged));

public double RotationZ
{
    get { return this.GetValue<double>(RotationZProperty); }
    set { SetValue(RotationZProperty, value); }
}

public double RotationY
{
    get { return this.GetValue<double>(RotationYProperty); }
    set { SetValue(RotationYProperty, value); }
}

public double RotationX
{
    get { return this.GetValue<double>(RotationXProperty); }
    set { SetValue(RotationXProperty, value); }
}

public FrameworkElement Child
{
    get;
    set;
}

static private void OnRotationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is Projection pl)
            {
                pl.OnRotationChanged();
            }
        }

        private void OnRotationChanged()
        {
            // Some code
        }}

After that, we have the PlaneProjectionClass :

     [ContentProperty("Child")]
    sealed public class PlaneProjection
        : Projection
    {   
    }

Tile类使用Projection:

类型的依赖项属性
     public class Tile
    {
     static public readonly DependencyProperty PlaneProjectionProperty = DependencyProperty.Register(
            nameof(Projection),
            typeof(Projection),
            typeof(Tile),
            new UIPropertyMetadata());

 public Projection Projection
        {
            get { return (Projection)GetValue(PlaneProjectionProperty); }
            private set { SetValue(PlaneProjectionProperty, value); }
        }

        override public void OnApplyTemplate()
        {
            Projection = GetTemplateChild("PART_Projection") as Projection;
        }
     }

因此对于XAML,我们在ControlTemplate中有这个:

    <controls:PlaneProjection x:Name="PART_PlaneProjection">
    <Border>
    <Grid>
      <!-- Some design -->
    </Grid>
    </Border>
</controls:PlaneProjection>

现在我想为平面投影设置动画。

所以我创建了故事板并使用rotationX:

为投影设置动画
static public void CreateAnimation(Tile tile)
{
    Storyboard.SetTarget(anim, tile);
    Storyboard.SetTargetProperty(doubleAnim, new PropertyPath("(Tile.Projection).(PlaneProjection.RotationX"));
 }

但是在调试时,我有这样的错误:无法解析属性路径上属性的所有引用&#39;(Tile.Projection)。(PlaneProjection.RotationX)

我不明白这个错误:(关于在自定义控件上使用PropertyPath的任何想法?

1 个答案:

答案 0 :(得分:3)

Tile类中的Projection属性不遵循依赖项属性的命名约定。

它应该例如看起来像这样:

public static readonly DependencyProperty PlaneProjectionProperty =
    DependencyProperty.Register(nameof(PlaneProjection), typeof(Projection), typeof(Tile));

public Projection PlaneProjection
{
    get { return (Projection)GetValue(PlaneProjectionProperty); }
    private set { SetValue(PlaneProjectionProperty, value); }
}

属性路径就是这样:

Storyboard.SetTargetProperty(anim, new PropertyPath("PlaneProjection.RotationX"));

你甚至不需要故事板。只需致电

tile.PlaneProjection.BeginAnimation(Projection.RotationXProperty, anim);

作为注释,私有setter不会将依赖项属性设置为只读。有关详细信息,请参阅Read-Only Dependency Properties