在XAML中设置时,IEnumerable DependencyProperty会引发错误

时间:2010-06-21 14:47:38

标签: wpf xaml ienumerable dependency-properties

我有一个继承自Workspace的自定义控件Control,其内部是DependencyProperty我需要包含用户指定的IEnumerable<IFoo>(我也尝试过)使其成为非通用的IEnumerable)。

Public Shared ReadOnly FoosProperty As DependencyProperty = DependencyProperty.Register("Foos", GetType(IEnumerable(Of IFoo)), GetType(Workspace), New FrameworkPropertyMetadata())
Public Property Foos() As IEnumerable(Of IFoo)
    Get
        Return CType(Me.GetValue(FoosProperty), IEnumerable(Of IFoo))
    End Get
    Set(ByVal value As IEnumerable(Of IFoo))
        Me.SetValue(FoosProperty, CType(value, IEnumerable(Of IFoo)))
    End Set
End Property

当我在代码中创建并设置IFoo数组时,一切都很完美,但是当我尝试在XAML中添加它们时,我会收到错误。如果我添加一个IFoo,我会收到错误

  1. “'FooItem'不是属性'Foos'的有效值。”
  2. 在运行时。如果我尝试添加多个IFoo项,我会在编译时遇到三个错误

    1. 对象'Workspace'已经有一个子节点,无法添加'FooItem'。 “工作区”只能接受一个孩子。
    2. 属性'Foos'不支持'FooItem'类型的值。
    3. 属性'Foos'不止一次。
    4. 我读错误意味着WPF没有像往常那样将xaml转换为项目数组。以下是我尝试在XAML中添加项目的方法

      <Workspace>
          <Workspace.Foos>
              <FooItem />
              <FooItem />
          </Workspace.Foos>
      </Workspace>
      

      我过去创建了类似的DependencyProperties,从来没有遇到过问题所以我猜我错过了一些简单的东西。

      感谢您的帮助!

1 个答案:

答案 0 :(得分:9)

为了能够添加多个元素,collection属性必须是IListIDictionary。当它是IEnumerable时,XAML解析器尝试将第一个值分配给属性本身(而不是像列表那样调用Add),并对连续项目感到困惑。这是您的错误的来源。

另外,如果你想从XAML填充集合,请确保你的列表是实例化的,而不是空的,因为XAML不会为你实例化列表,它只需要调用Add就可以了。因此,为了避免NullReferenceException,请删除IList属性上的setter并从构造函数中实例化列表。

它不一定是依赖属性:

private readonly ObservableCollection<FooItem> _foos = new ObservableCollection<FooItem>();

public ObservableCollection<FooItem> Foos
{
    get { return _foos; }
}