Peter
Peter

Reputation: 1687

Initialize Collection of DataTemplates in XAML

I have this DependencyProperty

public ObservableCollection<DataTemplate> WizardTemplateCollection
{
    get { return (ObservableCollection<DataTemplate>)GetValue(WizardTemplateCollectionProperty); }
    set { SetValue(WizardTemplateCollectionProperty, value); }
}

// Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty WizardTemplateCollectionProperty =
    DependencyProperty.Register("WizardTemplateCollection", typeof(ObservableCollection<DataTemplate>), typeof(CustomWizardControl), new PropertyMetadata(new ObservableCollection<DataTemplate>()));

And want to do this:

<custom:CustomWizardControl>
    <custom:CustomWizardControl.WizardTemplateCollection>
        <DataTemplate>
            <Rectangle></Rectangle>
        </DataTemplate>
        <DataTemplate>
            <Rectangle></Rectangle>
        </DataTemplate>
        <DataTemplate>
            <Rectangle></Rectangle>
        </DataTemplate>
    </custom:CustomWizardControl.WizardTemplateCollection>
</custom:CustomWizardControl>

What DataType do i need? Or how can i initialize a ObservableCollection in XAML.

Additional:

public class CustomWizardControl : Control {}

Upvotes: 0

Views: 355

Answers (2)

mm8
mm8

Reputation: 169330

Your CustomWizardControl class must inherit from DepenedencyObject or one of its derived types like for example UIElement or Control:

public class CustomWizardControl : Control
{
    public ObservableCollection<DataTemplate> WizardTemplateCollection
    {
        get { return (ObservableCollection<DataTemplate>)GetValue(WizardTemplateCollectionProperty); }
        set { SetValue(WizardTemplateCollectionProperty, value); }
    }
    ...
}

This works:

public class CustomWizardControl : Control
{
    public CustomWizardControl()
    {
        WizardTemplateCollection = new ObservableCollection<DataTemplate>();
    }

    public ObservableCollection<DataTemplate> WizardTemplateCollection
    {
        get { return (ObservableCollection<DataTemplate>)GetValue(WizardTemplateCollectionProperty); }
        set { SetValue(WizardTemplateCollectionProperty, value); }
    }

    public static readonly DependencyProperty WizardTemplateCollectionProperty =
        DependencyProperty.Register("WizardTemplateCollection", typeof(ObservableCollection<DataTemplate>), typeof(CustomWizardControl), new PropertyMetadata(null));
}

<local:CustomWizardControl x:Name="ctrl">
    <local:CustomWizardControl.WizardTemplateCollection>
        <DataTemplate>
            <Rectangle></Rectangle>
        </DataTemplate>
        <DataTemplate>
            <Rectangle></Rectangle>
        </DataTemplate>
        <DataTemplate>
            <Rectangle></Rectangle>
        </DataTemplate>
    </local:CustomWizardControl.WizardTemplateCollection>
</local:CustomWizardControl>

<TextBlock Text="{Binding WizardTemplateCollection.Count, ElementName=ctrl}" />

Upvotes: 1

Pavel
Pavel

Reputation: 910

You cannot set the generic parameter of ObservableCollection<T> directly in XAML.

Instead you should create your custom DataTemplateCollection inherited from ObservableCollection<DataTemplate>. Then you will be able to use your collection as usual.

public class DataTemplateCollection : ObservableCollection<DataTemplate>
{
}

<custom:CustomWizardControl>
    <custom:CustomWizardControl.WizardTemplateCollection>
        <custom:DataTemplateCollection>
            <DataTemplate>
                <Rectangle></Rectangle>
            </DataTemplate>
            <DataTemplate>
                <Rectangle></Rectangle>
            </DataTemplate>
            <DataTemplate>
                <Rectangle></Rectangle>
            </DataTemplate>
        </custom:DataTemplateCollection>
    </custom:CustomWizardControl.WizardTemplateCollection>
</custom:CustomWizardControl>

Additional note: NEVER initialize the default value of dependency properties with mutable objects, because this single mutable instance will be used by every control instance. Instead you must set the default value to null and assing the initial value in the constructor.

Upvotes: 0

Related Questions