Cameron MacFarland
Cameron MacFarland

Reputation: 71856

How to make a custom WPF collection?

I'm trying to create a custom set of classes that can be added to a WPF control through XAML.

The problem I'm having is adding items to the collection. Here's what I have so far.

public class MyControl : Control
{
    static MyControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(typeof(MyControl)));
    }

    public static DependencyProperty MyCollectionProperty = DependencyProperty.Register("MyCollection", typeof(MyCollection), typeof(MyControl));
    public MyCollection MyCollection
    {
        get { return (MyCollection)GetValue(MyCollectionProperty); }
        set { SetValue(MyCollectionProperty, value); }
    }
}

public class MyCollectionBase : DependencyObject
{
    // This class is needed for some other things...
}

[ContentProperty("Items")]
public class MyCollection : MyCollectionBase
{
    public ItemCollection Items { get; set; }
}

public class MyItem : DependencyObject { ... }

And the XAML.

<l:MyControl>
    <l:MyControl.MyCollection>
        <l:MyCollection>
            <l:MyItem />
        </l:MyCollection>
    </l:MyControl.MyCollection>
</l:MyControl>

The exception is:
System.Windows.Markup.XamlParseException occurred Message="'MyItem' object cannot be added to 'MyCollection'. Object of type 'CollectionTest.MyItem' cannot be converted to type 'System.Windows.Controls.ItemCollection'.

Does any one know how I can fix this? Thanks

Upvotes: 3

Views: 6030

Answers (2)

Cameron MacFarland
Cameron MacFarland

Reputation: 71856

After more googling, I found this blog which had the same error message. Seems I need to implement IList as well.

public class MyCollection : MyCollectionBase,  IList
{
    // IList implementation...
}

Upvotes: 3

Pavel Minaev
Pavel Minaev

Reputation: 101565

Did you perhaps forget to create an instance of ItemCollection in the constructor of MyCollection, and assign it to Items property? For XAML parser to add items, it needs an existing collection instance. It won't create a new one for you (though it will let you create one explicitly in XAML if the collection property has a setter). So:

[ContentProperty("Items")]
public class MyCollection : MyCollectionBase
{
    public ObservableCollection<object> Items { get; private set; }

    public MyCollection()
    {
         Items = new ObservableCollection<object>();
    }
}

Upvotes: 1

Related Questions