我正在尝试使用标记扩展提供的值填充collection(list)属性。 如果提供集合的属性具有公共setter,则执行此操作会出现问题。 我认为这是XAML实现中的一个错误(使用.NET 3.5),但我不确定。
考虑以下测试类
[ContentProperty("SettableList")]
public class Test : FrameworkElement
{
List<string> _settableList = new List<string>();
List<string> _justGettableList = new List<string>();
public List<string> SettableList { get { return _settableList; } set { _settableList = value; } }
public List<string> JustGettableList { get { return _settableList; } }
}
和以下标记扩展,它只提供一个字符串。
public class ProvideStringExtension : MarkupExtension
{
public override object ProvideValue(IServiceProvider serviceProvider)
{
return "Blah";
}
}
现在以下测试用例都可以正常工作: Hurz
<!-- b) fill SettableList with explicit string: ok -->
<local:Test>
<local:Test.SettableList>
<sys:String>Hurz</sys:String>
</local:Test.SettableList>
</local:Test>
<!-- c) fill JustGettableList with string from markup extension: ok -->
<local:Test>
<local:Test.JustGettableList>
<local:ProvideStringExtension/>
</local:Test.JustGettableList>
</local:Test>
<!-- d) fill SettableList with string form markup extension by using "ContentProperty": ok -->
<local:Test>
<local:ProvideStringExtension/>
</local:Test>
但是这个测试用例失败了:
<!-- e) fill SettableList with string from markup extension: FAILS -->
<!-- Throws (tries to convert the provided string to List<string>) -->
<local:Test>
<local:Test.SettableList>
<local:ProvideStringExtension/>
</local:Test.SettableList>
</local:Test>
失败的情况会抛出一个异常,说'string'无法转换为'List'。 有没有解释为什么这种情况失败,因为类似的情况d)和c)工作正常?
答案 0 :(得分:0)
XAML解析器尝试做的第一件事就是获取你得到的值并将属性“设置”为该值。所以它想要这样做:
this.SettableList = ProvideStringExtension.ProvideValue();
如果没有setter并且属性实现ICollection(可能是IList,我忘了),那么它会尝试将该项添加到集合中:
this.JusetGettableList.Add(ProvideStringExtension.ProvideValue())
他们可能已经改变了这种逻辑,但我确信有这样做的设计选择。
另外,我相信即使setter是私有的,它仍然会失败。但这可能已经解决了。