我有一个类AdvanceBasicEffect,它有一个属性SpecularColor,它是类AdvanceVector3类的对象,所以当我绑定specularColor.X属性时,属性更改事件触发但仅在AdvanceVector3类中不在AdvanceBasicEffect中。
查看您将要弄清楚的代码:
public partial class Lights : UserControl
{
public Lights()
{
InitializeComponent();
this.DataContext = this;
basicEffect = new AdvanceBasicEffect();
}
public AdvanceBasicEffect basicEffect { get; set; }
}
public class AdvanceBasicEffect : INotifyPropertyChanged
{
public AdvanceBasicEffect()
{
SpecularColor = new AdvanceVector3();
basicEffect = ((bathroom)CurrentWindowHandle.currentGame.Components.First()).basicEffect;
}
BasicEffect basicEffect;
AdvanceVector3 _SpecularColor;
public AdvanceVector3 SpecularColor
{
get
{
return _SpecularColor;
}
set
{
//Line 1 : event not occuring
_SpecularColor = value;
if(basicEffect!=null)
basicEffect.DirectionalLight0.Direction = new Vector3(_SpecularColor.X, _SpecularColor.Y, _SpecularColor.Z);
valueChanged("SpecularColor");
}
}
private void valueChanged(string p)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(p));
CurrentWindowHandle.currentGame.models[0].SetMeshEffect("Archinteriors7_10_80", basicEffect, false);
CurrentWindowHandle.currentGame.models[0].SetMeshEffect("Archinteriors7_10_111", basicEffect, false);
CurrentWindowHandle.currentGame.models[0].SetMeshEffect("Archinteriors7_10_112", basicEffect, false);
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class AdvanceVector3 : INotifyPropertyChanged
{
float _X;
public float X
{
get
{
return _X;
}
set
{
_X = value;
valueChanged("X");
}
}
float _Y;
public float Y
{
get
{
return _Y;
}
set
{
_Y = value;
valueChanged("Y");
}
}
float _Z;
public float Z
{
get
{
return _Z;
}
set
{
_Z = value;
valueChanged("Z");
}
}
private void valueChanged(string p)
{
//line 2 :Event Occuring
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(p));
//CurrentWindowHandle.currentGame.models[0].SetMeshEffect("Archinteriors7_10_80", basicEffect, false);
//CurrentWindowHandle.currentGame.models[0].SetMeshEffect("Archinteriors7_10_111", basicEffect, false);
//CurrentWindowHandle.currentGame.models[0].SetMeshEffect("Archinteriors7_10_112", basicEffect, false);
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
在评论“第1行”事件发生时,在“第2行”事件发生时,所以我的问题是当子属性发生变化时,为什么父属性没有发生变化。我不能在同一个类中定义X,Y,Z,因为我有许多属性需要AdvanceVector3类
绑定代码如下:
<Slider ToolTip="SpecularColorX" Minimum="-1" Maximum="1" Value="{Binding basicEffect.SpecularColor.X}" />
<Slider ToolTip="SpecularColorY" Minimum="-1" Maximum="1" Value="{Binding basicEffect.SpecularColor.Y}" />
<Slider ToolTip="SpecularColorZ" Minimum="-1" Maximum="1" Value="{Binding basicEffect.SpecularColor.Z}" />
答案 0 :(得分:4)
如果我正确地回答了您的问题,我认为您误解了INPC的含义以及何时触发。
如果你说有
Class ParentClass : INotifyPropertyChanged {
public ChildClass SomeObject {
get { ... }
set { ... valueChanged("SomeObject"); }
}
...
}
和
Class ChildClass : INotifyPropertyChanged {
public string SomeString {
get { ... }
set { ... valueChanged("SomeString"); }
}
...
}
现在,如果您在SomeString
ParentClass
var parentObject = new ParentClass {SomeObject = new ChildClass {SomeString = "Hi"}};
// will trigger property changed in ChildClass for SomeString property
// however it will not trigger a PropertyChanged in ParentClass for SomeObject
parentObject.SomeObject.SomeString = "New String"
// will trigger property changed in ParentClass for SomeObject property
parentObject.SomeObject = new ChildClass();
您的xaml绑定工作正常,因为您直接绑定到属性,并且当它们更改时,View会相应地更新。
如果您想要“观察”SomeString
内ParentClass
的任何更改,那么您需要订阅PropertyChanged
ChildClass.SomeString
事件
所以说ParentClass
可以更新为
public ChildClass SomeObject {
get { ... }
set {
if (value == _someObject)
return;
_someObject.PropertyChanged -= ChildObjectValueChanged;
_someObject = value;
_someObject.PropertyChanged += ChildObjectValueChanged;
valueChanged("SomeObject"); }
}
private void ChildObjectValueChanged(object sender, PropertyChangedEventArgs args) {
if (args.PropertyName == "SomeString")
// Child Object property "SomeString" has changed. Do what you need here
}
答案 1 :(得分:0)
你的二传手永远不会被召唤。 Wpf本身在PropertyChagned
imlplementations上调用INotifyPropertyChanged
。你应该做的是在AdvancedBasicEffect
类构造函数中自己改变事件,而不是在valueChanged
方法中设置网格效果:
public AdvanceBasicEffect()
{
SpecularColor = new AdvanceVector3();
basicEffect = ((bathroom)CurrentWindowHandle.currentGame.Components.First()).basicEffect;
SpecularColor.PropertyChanged += (o,e) =>
{
CurrentWindowHandle.currentGame.models[0].SetMeshEffect("Archinteriors7_10_80", basicEffect, false);
CurrentWindowHandle.currentGame.models[0].SetMeshEffect("Archinteriors7_10_111", basicEffect, false);
CurrentWindowHandle.currentGame.models[0].SetMeshEffect("Archinteriors7_10_112", basicEffect, false);
}
}