Как устранить ошибку дизайнера WPF «Тип {0} не поддерживает прямой контент». »?

Следующий XAML (ниже) определяет пользовательскую коллекцию в ресурсах и пытается заполнить ее пользовательским объектом;

<UserControl x:Class="ImageListView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="300" Height="300"
    xmlns:local="clr-namespace:MyControls" >
    <UserControl.Resources>
        <local:MyCustomCollection x:Key="MyKey">
            <local:MyCustomItem>
            </local:MyCustomItem>
        </local:MyCustomCollection>
    </UserControl.Resources>
</UserControl>

Проблема в том, что я получаю сообщение об ошибке в конструкторе типа «MyCustomCollection» не поддерживает прямой контент ». Я попытался установить ContentProperty, как советовали в MSDN, но не могу понять, на что его установить. Пользовательский объект коллекции, который я использую, находится ниже и очень прост. Я пробовал Item, Items и MyCustomItem и не могу придумать, что еще можно попробовать.

<ContentProperty("WhatGoesHere?")> _
Public Class MyCustomCollection
    Inherits ObservableCollection(Of MyCustomItem)
End Class

Любые подсказки о том, где я иду не так, будут с благодарностью приняты. Также подсказки о том, как копаться в объектной модели WPF, чтобы увидеть, какие свойства предоставляются во время выполнения, я мог бы также понять это.

С уважением

Райан

10.12.2008 16:27:36
1 ОТВЕТ
РЕШЕНИЕ

Вы должны инициализировать ContentPropertyAttribute с именем свойства, которое будет представлять содержимое вашего класса. В вашем случае, поскольку вы наследуете от ObservableCollection, это будет свойство Items. К сожалению, свойство Items доступно только для чтения, и это недопустимо, поскольку свойство Content должно иметь установщик. Таким образом, вы должны определить собственное свойство-оболочку для Items и использовать его в своем атрибуте, например так:

public class MyCustomItem
{ }

[ContentProperty("MyItems")]
public class MyCustomCollection : ObservableCollection<MyCustomItem>
{
    public IList<MyCustomItem> MyItems
    {
        get { return Items; }
        set 
        {
            foreach (MyCustomItem item in value)
            {
                Items.Add(item);
            }
       }
    }
}

И с тобой должно быть все в порядке. Извините за то, что вы делаете это в C #, когда ваш пример написан на VB, но я действительно отстой в VB и не могу понять даже такую ​​простую вещь правильно ... В любом случае, это совсем несложно преобразовать, так что - надеюсь, это поможет.

5
10.12.2008 17:14:16
Выглядит хорошо, но вопрос о вашем сеттере есть. Не будет ли это просто постоянно добавлять в коллекцию и вызывать исключение? Кроме того, почему IList, а не ObservableCollection? Спасибо
Ryan O'Neill 10.12.2008 17:08:59
Нет, он добавит только столько элементов, сколько у вас есть в переменной входящего значения - и это те значения, которые вы определили в XAML. И это IList <T>, потому что это тип свойства Items. Помните, что оболочка предназначена для свойства Items, а не для всего класса.
Boyan 10.12.2008 17:13:04
Теперь я получил «Этот элемент представляет значение по умолчанию и не может быть изменен». в конструкторе. Возможно, мне нужно использовать синтаксис сеттера.
Ryan O'Neill 10.12.2008 17:19:41
Я не понимаю эту ошибку, но я не знаю, что именно вы пытаетесь сделать. Не могли бы вы указать?
Boyan 10.12.2008 17:33:31
Есть и другая проблема. Свойство Content допускает только один фрагмент содержимого - поэтому, если вы попытаетесь вставить второй MyCustomItem в XAML, вы получите ошибку. Если это не имеет значения, вы должны искать другое решение, которое не использует ContentPropertyAttribute.
Boyan 10.12.2008 17:34:13