Search code examples
wpfwpf-controlscustom-controlscontrol-template

How to modify ControlTemplate to add items directly to my custom control


I have defined following control template for my custom control.

<ControlTemplate TargetType="{x:Type local:CustomControl}">
    <Grid x:Name="MainGrid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <local:CustomPanel x:Name="MyCustomPanel" Grid.Column="0" />
        <ScrollBar Grid.Column="1" Width="20" />
    </Grid>
</ControlTemplate>

Here the CustomPanel derives form Panel class. Now I cannot add the items to my CustomControl directly like this

<local:CustomControl x:Name="CControl" Grid.Row="1">
    <Button/>
    <Button/>
    <Button/>
</local:CustomControl>

What can I do for adding the items to my custom control directly from XAML?


Solution

  • Here is a sample control that allows you to directly add content in the way that you're after.

    The lines of interest here are the attribute on top of the MyCustomControl class, this tells the XAML editor which property any directly added content should be placed in.

    In the XAML code the important line is the ItemsControl that's bound to the Items property, this actually displays each item.

    C#

    [ContentProperty("Items")]
    public class MyCustomControl : Control
    {
        public ObservableCollection<Object> Items
        {
            get { return (ObservableCollection<Object>)GetValue(ItemsProperty); }
            set { SetValue(ItemsProperty, value); }
        }
    
        public static readonly DependencyProperty ItemsProperty =
            DependencyProperty.Register("Items", typeof(ObservableCollection<Object>), typeof(MyCustomControl), new UIPropertyMetadata(new ObservableCollection<object>()));        
    }
    

    XAML

    <Style TargetType="{x:Type local:MyCustomControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:MyCustomControl}">
                    <ItemsControl ItemsSource="{TemplateBinding Items}"  />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
    <local:MyCustomControl>
        <Button />
        <Button />
    </local:MyCustomControl>