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

Bry*_*son 0 wpf ienumerable xaml 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
Run Code Online (Sandbox Code Playgroud)

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

  1. "'FooItem'不是物业'Foos'的有效价值."

在运行时.如果我尝试添加多个IFoo项目,我会在编译时遇到三个错误

  1. 对象'Workspace'已经有一个子节点,无法添加'FooItem'."工作区"只能接受一个孩子.
  2. 属性'Foos'不支持'FooItem'类型的值.
  3. 酒店'Foos'不止一次.

我读错误意味着WPF没有像往常那样将xaml转换为项目数组.以下是我尝试在XAML中添加项目的方法

<Workspace>
    <Workspace.Foos>
        <FooItem />
        <FooItem />
    </Workspace.Foos>
</Workspace>
Run Code Online (Sandbox Code Playgroud)

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

谢谢你的帮助!

rep*_*pka 9

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

此外,如果您想从XAML填充集合,请确保您的列表已实例化而不是以null为开头,因为XAML不会为您实例化列表,它只会调用Add它.所以要避免NullReferenceException,摆脱IList属性上的setter 并从构造函数实例化列表.

它不必是依赖属性:

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

public ObservableCollection<FooItem> Foos
{
    get { return _foos; }
}
Run Code Online (Sandbox Code Playgroud)