2013-06-22 156 views
1

我有一个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

Praent财产变化应该发生。你确定你改变了'SpecularColor'而不是你的代码中的'_SpecularColor'字段吗?请告诉我们X/Y/Z如何变化 – ghord

+0

我已经显示当我移动滑块时绑定代码(X,Y,Z)发生变化 –

回答

4

如果我正确地遵循你的问题,我想你误会什么INPC意味着,当它触发。

如果你说有

Class ParentClass : INotifyPropertyChanged { 

    public ChildClass SomeObject { 
    get { ... } 
    set { ... valueChanged("SomeObject"); } 
    } 

    ... 

} 

Class ChildClass : INotifyPropertyChanged { 

    public string SomeString { 
    get { ... } 
    set { ... valueChanged("SomeString"); } 
    } 

    ... 

} 

现在,如果你无论是从XAML或代码隐藏在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中绑定的对象发生变化SomeString因为你直接绑定到属性和as和whe,所以工作得很好他们改变你的观点相应地更新。

如果你是想从ParentClass内以“守”的任何更改SomeString,那么你需要订阅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 
    } 
+0

非常感谢我的理解我的问题,这是解决我的问题。谢谢 –

0

你制定者不会被调用。 Wpf本身在INotifyPropertyChanged的实现中调用PropertyChagned。你应该做的是subsribe到更改事件自己在你的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); 
    } 
} 
+0

NO这不起作用,因为当滑块移动时,只有AdvanceVector3类的属性发生变化, AdvanceBasicEffect类不受影响。 –

+0

@Shivam cv您是否尝试过使用'SpecularColor.PropertyChanged'继承?我想都应该工作... – ghord

+0

是的,它是同样的事情,但不工作。但如果我创建另一个属性,让我们把int类型的“SpecularPower”并绑定它,然后它工作,因为滑块正在改变specularPower属性本身,但这里的情况是不同的 –

相关问题