【问题标题】:Filling collection property with markup extensions fails in XAML在 XAML 中使用标记扩展填充集合属性失败
【发布时间】:2011-04-08 23:32:30
【问题描述】:

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

现在以下测试用例都可以正常工作: 赫兹

<!-- 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) 工作正常?

【问题讨论】:

    标签: wpf xaml markup-extensions


    【解决方案1】:

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

    this.SettableList = ProvideStringExtension.ProvideValue();
    

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

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

    他们可能会颠倒这个逻辑,但我确信这样做是出于设计上的选择。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-20
      • 2012-01-08
      • 1970-01-01
      • 1970-01-01
      • 2011-03-02
      • 1970-01-01
      • 2011-03-11
      相关资源
      最近更新 更多