You have a number of problems. Firstly, you are using RelativeSource TemplatedParent , but this is not binding to the element inside the template, so you should use Self . This can be done relatively easily:
<DataTrigger Value="True" Binding="{Binding Path=IsLightOnVal[0].Value, RelativeSource={RelativeSource Self}}">
Secondly, you have defined this property as a CLR property (with its own repository) and as DependencyProperty. If the property is defined as DP, then the system expects you to use DP to store the value. In code, you never use the SetValue method to actually store the collection instance in the DependencyObject backup storage. Therefore, there are several ways to fix this:
1) Remove DP:
//public static readonly DependencyProperty IsLightOnValProperty = // DependencyProperty.Register( "IsLightOnVal", typeof( System.Collections.ObjectModel.ObservableCollection<CtlStateBool> ), typeof( ButtonSimple ), new UIPropertyMetadata( new System.Collections.ObjectModel.ObservableCollection<CtlStateBool>() ) );
Since this is not DP, although you cannot install it in the setter, bind it to some property on your virtual machine, etc., so this is probably not the best option.
2) Store the value in DP as well as the local variable:
public System.Collections.ObjectModel.ObservableCollection<CtlStateBool> IsLightOnVal { get { if ( m_IsLightOnVal == null ) this.SetValue(IsLightOnValProperty, m_IsLightOnVal = new System.Collections.ObjectModel.ObservableCollection<CtlStateBool>()); return m_IsLightOnVal; } set { if ( m_IsLightOnVal != value ) { this.SetValue( IsLightOnValProperty, m_IsLightOnVal = value ); OnPropertyChanged( "IsLightOnVal" ); } } }
I personally donโt like it. Or, more specifically, I believe that his bad practice lazily distributes your own property in a getter. This will set a local value for the object, which can overwrite the actual value if someone really set it with a lower priority (for example, an instance of this parameter was defined in the template and the property set / associated with it). And if you plan to support development time, this can ruin the designer. If you go along this route, then really you should add PropertyChangedHandler to your DP definition and do not forget to set the m_IsLightOnVal member variable in it, otherwise you will exit synchronization if the value is set via DP (for example, someone including the WPF structure - uses SetValue to set the property value).
3) Use only GetValue / SetValue
public System.Collections.ObjectModel.ObservableCollection<CtlStateBool> IsLightOnVal { get { return (System.Collections.ObjectModel.ObservableCollection<CtlStateBool>)this.GetValue(IsLightOnValProperty); } set { this.SetValue( IsLightOnValProperty, value ); } }
I would recommend this approach. Yes, this means that anyone who wants to set a property must define an instance of the collection, but I think that it is preferable to the problems that you could hit if you set your own DP value. Note that if you go through this route, you may need to define a non-generic generic class that will be derived from the ObservableCollection so that someone can define an instance of the collection class in xaml, although if you expect this to be just related may not be a problem. From a comment on another answer, although it seems that it can be installed in haml.