如何检测子属性是否被改变
How to detect if a sub-property is changed
我想为 ModelVisual3D 制作动画,但我无法检测到父对象的参照系何时更改。
我有一个 class FrameOfReference,它是一个使用 ZYX 欧拉角来描述方向的 3D 坐标系。此 class 有一个 TransformGroup 属性,它反映了每当 X、Y、Z、A、B 或 C 发生变化时更新的框架位置。与 ZYX 欧拉角交互以创建变换对我来说非常重要,而不是 TransformGroup。
我还有一个 class EOAT ("end of arm tool"),它具有 FrameOfReference 和 ModelVisual3D 属性。如果 FrameOfReference 的 属性 已更改,我正在尝试更新 ModelVisual3D。
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;}
}
}
我的 class 是 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”,_eoat 中的 FrameOfReference 不会检测到框架已更改,因此不会使用 CreateModel() 更新模型。我知道我可以在更改帧后手动调用 CreateModel() ,但是当需要做动画故事板时这将不起作用,因为动画只是随时间改变一个值并且不能在动画期间调用 CreateModel() .
简而言之,如何让 EOAT 在 Frame 内的任何内容发生更改时自动调用 CreateModel()。我已经尝试了 INotifyPropertyChange 代码,但还没有得到任何工作。
对所有内容感到抱歉。我希望这个问题是有道理的。谢谢。
您只需将事件处理程序添加到 FrameOfReference
的 NotifyPropertyChanged
事件,然后从事件处理程序调用 CreateModel
。
public EOATModel()
{
Frame = new FrameOfReference();
Frame.PropertyChanged += (o,e) => CreateModel());
}
我想为 ModelVisual3D 制作动画,但我无法检测到父对象的参照系何时更改。
我有一个 class FrameOfReference,它是一个使用 ZYX 欧拉角来描述方向的 3D 坐标系。此 class 有一个 TransformGroup 属性,它反映了每当 X、Y、Z、A、B 或 C 发生变化时更新的框架位置。与 ZYX 欧拉角交互以创建变换对我来说非常重要,而不是 TransformGroup。
我还有一个 class EOAT ("end of arm tool"),它具有 FrameOfReference 和 ModelVisual3D 属性。如果 FrameOfReference 的 属性 已更改,我正在尝试更新 ModelVisual3D。
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;}
}
}
我的 class 是 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”,_eoat 中的 FrameOfReference 不会检测到框架已更改,因此不会使用 CreateModel() 更新模型。我知道我可以在更改帧后手动调用 CreateModel() ,但是当需要做动画故事板时这将不起作用,因为动画只是随时间改变一个值并且不能在动画期间调用 CreateModel() .
简而言之,如何让 EOAT 在 Frame 内的任何内容发生更改时自动调用 CreateModel()。我已经尝试了 INotifyPropertyChange 代码,但还没有得到任何工作。
对所有内容感到抱歉。我希望这个问题是有道理的。谢谢。
您只需将事件处理程序添加到 FrameOfReference
的 NotifyPropertyChanged
事件,然后从事件处理程序调用 CreateModel
。
public EOATModel()
{
Frame = new FrameOfReference();
Frame.PropertyChanged += (o,e) => CreateModel());
}