1

我正在尝试使用标记扩展提供的值填充集合(列表)属性。如果提供集合的属性具有公共设置器,则执行此操作会出现问题。我认为这是 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>

失败的情况会引发一个异常,指出“字符串”不能转换为“列表”。有没有解释为什么这会失败,因为类似的情况 d) 和 c) 工作正常?

4

1 回答 1

0

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

this.SettableList = ProvideStringExtension.ProvideValue();

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

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

他们可能会颠倒这个逻辑,但我确信有一个设计选择可以这样做。

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

于 2011-04-08T15:32:30.220 回答