IEnumerable DependencyProperty выдает ошибки при установке в XAML - PullRequest
0 голосов
/ 21 июня 2010

У меня есть пользовательский элемент управления 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 "."

во время выполнения.Если я пытаюсь добавить несколько элементов IFoo, я получаю три ошибки во время компиляции

  1. Объект «Рабочая область» уже имеет дочерний элемент и не может добавить «FooItem».«Рабочая область» может принимать только одного дочернего элемента.
  2. Свойство «Foos» не поддерживает значения типа «FooItem».
  3. Свойство «Foos» задается более одного раза.

Я прочитал ошибки, чтобы показать, что WPF не преобразует xaml в массив элементов, как это обычно бывает.Вот как я пытаюсь добавить элементы в XAML

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

В прошлом я создавал аналогичные свойства DependencyProperties, и у меня никогда не было проблем, поэтому я предполагаю, что упускаю что-то простое.

Спасибо за любую помощь!

1 Ответ

9 голосов
/ 21 июня 2010

Чтобы иметь возможность добавить несколько элементов, свойство коллекции должно быть IList или IDictionary.Когда это IEnumerable XAML-парсер пытается присвоить первое значение самому свойству (вместо вызова Add как со списками) и запутывается в последовательных элементах.Это источник ваших ошибок.

Кроме того, если вы хотите заполнить коллекцию из XAML, убедитесь, что ваш список создан, и для него не пусто, поскольку XAML не будет создавать для вас список, он просто вызовет AddЭто.Поэтому, чтобы избежать NullReferenceException, избавьтесь от сеттера в свойстве IList и создайте список экземпляров из конструктора.

Это не должно быть свойство зависимости:

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

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