I understand that interesting things happen to attached properties in datatemplates but this one is very strange.
I have a behavior with a dependency property on it, the property is type List<DataStatePair>
[System.Windows.Markup.ContentProperty("StateDefinitions")]
public class MultiDataStateBehavior: StateBehaviourBase
{
public List<DataStatePair> StateDefinitions
{
get { return (List<DataStatePair>)GetValue(StateDefinitionsProperty); }
set { SetValue(StateDefinitionsProperty, value); }
}
// Using a DependencyProperty as the backing store for StateDefinitions. This enables animation, styling, binding, etc...
public static readonly DependencyProperty StateDefinitionsProperty =
DependencyProperty.Register("StateDefinitions", typeof(List<DataStatePair>), typeof(MultiDataStateBehavior), new PropertyMetadata(new List<DataStatePair>()));
}
As you can see, I've marked it as the content property. The XAML looks like this:
<DataTemplate>
<!-- VISUAL STATES OMITTED FOR BREVITY-->
<Grid x:Name="grid" Background="Transparent" ContextMenu="{StaticResource ContextMenu_ToolMenu}">
<i:Interaction.Behaviors>
<ext:MultiDataStateBehavior Binding="{Binding Type}">
<ext:DataStatePair State="None" Value="{x:Null}"/>
<ext:DataStatePair State="Gauge" Value="{x:Static jcm:ToolType.Gauge}"/>
<ext:DataStatePair State="Repeater" Value="{x:Static jcm:ToolType.Gauge}"/>
</ext:MultiDataStateBehavior>
</i:Interaction.Behaviors>
</Grid>
</DataTemplate>
The problem? 3 DataStatePair instances are added for each use of the datatemplate. I use the template 32 times in my app and get 96 DataStatePair instances in total. Grizzly! I understand how this is possible. The Behavior is static for the datatemplate but the DataStatePair instances are not and a List can be added to.
If change the dependency property to an IEnumerable everything breaks - it will not compile. If I set the property explicitly with an x:Array in XAML, everything works as expected - I only ever get 3 states. XAML below;
<i:Interaction.Behaviors>
<ext:MultiDataStateBehavior Binding="{Binding Type}" UseTransitionsOnLoad="True">
<ext:MultiDataStateBehavior.StateDefinitions>
<x:Array Type="{x:Type ext:DataStatePair}">
<ext:DataStatePair State="None" Value="{x:Null}"/>
<ext:DataStatePair State="Gauge" Value="{x:Static jcm:ToolType.Gauge}"/>
<ext:DataStatePair State="Repeater" Value="{x:Static jcm:ToolType.Gauge}"/>
</x:Array>
</ext:MultiDataStateBehavior.StateDefinitions>
</ext:MultiDataStateBehavior>
</i:Interaction.Behaviors>
Does anyone know why this is and what the most elegant solution is. I can imagine a Microsoft implementation would not make you use x:Array.
EDIT : The x:Array solution breaks the blend designer.
XamlParseException: Add value to collection of type 'System.Collections.Generic.IEnumerable(SSW.WPFExtensions.DataStatePair)' threw an exception.
EDIT : Removing the [System.Windows.Markup.ContentProperty("StateDefinitions")]
attribute definition works great. I dont understand what is going on!
WPF, what are you doing. WPF, STAHP