Datatemplates中的行为初始化

时间:2013-08-19 09:13:28

标签: wpf datatemplate attachedbehaviors

我理解有趣的事情发生在datatemplates中的附加属性,但这个很奇怪。

我有一个带有依赖项属性的行为,该属性是类型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>()));
}

如您所见,我已将其标记为内容属性。 XAML看起来像这样:

<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>

问题?每次使用datatemplate时都会添加3个DataStatePair实例。我在我的应用程序中使用模板32次,总共得到96个DataStatePair实例。灰熊!我理解这是可能的。对于datatemplate,行为是静态的,但DataStatePair实例不是,并且可以添加List。

如果将依赖项属性更改为IEnumerable,则一切都会中断 - 它将无法编译。如果我在XAML中使用x:Array显式设置属性,一切都按预期工作 - 我只有3个状态。 XAML在下面;

<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>

有谁知道这是为什么以及最优雅的解决方案是什么。我可以想象一个Microsoft实现不会让你使用x:Array。

编辑:x:Array解决方案打破了混合设计器。

  

XamlParseException:为类型集合添加值   'System.Collections.Generic.IEnumerable(SSW.WPFExtensions.DataStatePair)'   抛出异常。

编辑:删除[System.Windows.Markup.ContentProperty("StateDefinitions")]属性定义效果很好。我不明白发生了什么!

WPF,你在做什么WPF,STAHP

1 个答案:

答案 0 :(得分:1)

潜在的解决方案......这是一种愚蠢的行为。

Microsoft提供了有关创建集合的依赖项属性的指导 here

此文档指定您永远不应将属性的默认值声明为实例,而是在拥有类的构造函数中初始化集合并设置依赖项属性。例如

public Aquarium() : base()
{
    SetValue(AquariumContentsPropertyKey, new List<FrameworkElement>()); 
}
  

... [单个列表默认值]   值为水族馆的所有实例共享。如果你跑了   以下测试代码,旨在展示您的方式   实例化两个单独的Aquarium实例并添加一个不同的   钓到他们每个人,你会看到一个令人惊讶的结果:

至于我的设计时间异常。同样的问题是新的DataStatePair[0],它是不可变的,可怕的错误报告。

结论 - 微软的某个人不惜一切代价轻笑。