在XAML中,使用标记扩展填充集合属性失败

时间:2011-04-08 10:02:28

标签: wpf xaml markup-extensions

我正在尝试使用标记扩展提供的值填充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)工作正常?

1 个答案:

答案 0 :(得分:0)

XAML解析器尝试做的第一件事就是获取你得到的值并将属性“设置”为该值。所以它想要这样做:

this.SettableList = ProvideStringExtension.ProvideValue();

如果没有setter并且属性实现ICollection(可能是IList,我忘了),那么它会尝试将该项添加到集合中:

this.JusetGettableList.Add(ProvideStringExtension.ProvideValue())

他们可能已经改变了这种逻辑,但我确信有这样做的设计选择。

另外,我相信即使setter是私有的,它仍然会失败。但这可能已经解决了。