我理解有趣的事情发生在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
答案 0 :(得分:1)
潜在的解决方案......这是一种愚蠢的行为。
Microsoft提供了有关创建集合的依赖项属性的指导 here
此文档指定您永远不应将属性的默认值声明为实例,而是在拥有类的构造函数中初始化集合并设置依赖项属性。例如
public Aquarium() : base()
{
SetValue(AquariumContentsPropertyKey, new List<FrameworkElement>());
}
... [单个列表默认值] 值为水族馆的所有实例共享。如果你跑了 以下测试代码,旨在展示您的方式 实例化两个单独的Aquarium实例并添加一个不同的 钓到他们每个人,你会看到一个令人惊讶的结果:
至于我的设计时间异常。同样的问题是新的DataStatePair[0]
,它是不可变的,可怕的错误报告。
结论 - 微软的某个人不惜一切代价轻笑。