Как определить, изменилось ли подсвойство

Я хочу анимировать ModelVisual3D, но не могу определить, когда изменилась система отсчета родительского объекта.

У меня есть класс FrameOfReference, который представляет собой трехмерную координатную рамку, использующую углы Эйлера ZYX для описания ориентации. Этот класс имеет свойство TransformGroup, отражающее положение кадра, которое обновляется при каждом изменении X, Y, Z, A, B или C. Для меня очень важно, чтобы я взаимодействовал с углами Эйлера ZYX для создания преобразований, а не с TransformGroup.

У меня также есть класс EOAT ("инструмент конца руки"), который имеет свойства FrameOfReference и ModelVisual3D. Я пытаюсь обновить ModelVisual3D, если свойство FrameOfReference изменилось.

public class FrameOfReference
{
    private double _x, _y, _z, _a, _b, _c, _legLength;
    private ModelVisual3D _model;
    private Transform3DGroup _transformGroup;

    public FrameOfReference()
    {
        _x = 0;
        _y = 0;
        _z = 0;
        _a = 0;
        _b = 0;
        _c = 0;
    }

    public double X
    {
        get { return _x; }
        set { _x = value; UpdateTransformGroup();}
    }

    public double Y
    {
        get { return _y; }
        set {
            _y = value; UpdateTransformGroup();}
    }

    public double Z
    {
        get { return _z; }
        set { _z = value; UpdateTransformGroup();}
    }

    public double A
    {
        get { return _a; }
        set{ _a = value; UpdateTransformGroup();}
    }

    public double B
    {
        get { return _b; }
        set { _b = value; UpdateTransformGroup();}
    }

    public double C
    {
        get { return _c; }
        set { _c = value; UpdateTransformGroup();}
    }
    public void Transform3DGroup UpdateTransformGroup()
    {
            //convert ZYX Euler angles into a transformgroup
            Transform3DGroup group = new Transform3DGroup();
            Vector3D e = new Vector3D(C, B, A);
            Quaternion q = new Quaternion(new Vector3D(0.0, 0.0, 1.0), e.Z)
                * new Quaternion(new Vector3D(0.0, 1.0, 0.0), e.Y)
                * new Quaternion(new Vector3D(1.0, 0.0, 0.0), e.X);
            AxisAngleRotation3D r = new AxisAngleRotation3D(q.Axis, q.Angle);
            group.Children.Add(new RotateTransform3D(r));
            group.Children.Add(new TranslateTransform3D(X, Y, Z));
            _transformGroup = group;
    }
    public Transform3DGroup TransformGroup
    {
        get
        { return _transformGroup;}
        set { _transformGroup = value;}

    }
}

и мой класс, который является EOAT и содержит ModelVisual3D и FrameOfReference

class EOATModel
{

    private FrameOfReference _frame;
    private ModelVisual3D _model;

    public EOATModel()
    {
        Frame = new FrameOfReference();
    }

    public EOATModel(FrameOfReference Frame)
    {
        this.Frame = Frame;
    }

    public FrameOfReference Frame
    {
        get
        {
            return _frame;
        }
        set
        {
            _frame = value;
            CreateModel();
        }
    }

    public ModelVisual3D Model
    {
        get
        {
            return _model;
        }
        set
        {
            _model = value;
        }
    }

    public void CreateModel()
    {
        if (_model != null)
        {
            //--a bunch of code that makes the EOAT since its irrelevant--

            _model.Children.Add(EOATCube);
            _model.Transform = Frame.TransformGroup;
        }
    }

}

Некоторый пример кода, показывающий, как я делаю файл _eoat.

public class Main
{
    EOAT _eoat = new EOAT()
    _eoat.Frame.X = 100;
    _eoat.Frame.Y = 100;
    _eoat.Frame.Z = 100;
    _eoat.Frame.A = 100;
    _eoat.Frame.B = 100;
    _eoat.Frame.C = 100;
    _eoat.Model = new ModelVisual3D();
    viewPort3d.Children.Add(_eoat.Model);
    _eoat.Frame.C = 45;
}

Если я введу «_eoat.Frame.C = 45», FrameOfReference внутри _eoat не обнаружит, что кадр был изменен, и поэтому не обновит модель с помощью CreateModel(). Я знаю, что могу просто вручную вызвать CreateModel() после изменения кадра, но это не сработает, когда придет время делать раскадровку анимации, поскольку анимация просто меняет значение с течением времени и не может вызывать CreateModel() во время анимации. .

Короче говоря, как мне заставить EOAT автоматически вызывать CreateModel() всякий раз, когда что-либо внутри Frame изменяется. Я пробовал код INotifyPropertyChange, но ничего из этого не заработало.

Извините за весь контент. Я надеюсь, что этот вопрос имеет смысл. Спасибо.


person Micahstuh    schedule 27.03.2019    source источник


Ответы (1)


Вы можете просто добавить обработчик событий к событию NotifyPropertyChanged события FrameOfReference и вызвать CreateModel из обработчика событий.

public EOATModel()
{
    Frame = new FrameOfReference();
    Frame.PropertyChanged += (o,e) => CreateModel());
}
person Georg    schedule 27.03.2019
comment
Это была недостающая часть! Спасибо Георг. Теперь все, что мне нужно сделать, это выяснить, как сделать эти свойства зависимостей, чтобы я мог ссылаться на них в материалах раскадровки целевых свойств. - person Micahstuh; 27.03.2019